| 名称 | “amc-setup-calibration-stack” |
| 描述 | “通过 Docker Compose 从 NGC 发布镜像启动 AutoMagicCalib 微服务和 Web UI。当用户说“部署自动标定”、“启动自动标定”、“启动 AMC”、“启动 MS+UI”或“设置 auto-magic-calib”时使用。需要 NGC API 密钥。” metadata: |
| 作者 | “NVIDIA CORPORATION” tags: [amc, deepstream, docker, calibration, setup, ngc] owner: “NVIDIA CORPORATION” service: “auto-magic-calib” |
| 版本 | “1.0.0” reviewed: “2026-04-28” |
| 开源协议 | “Apache-2.0” |
技能:启动 AutoMagicCalib 发布容器
从发布容器配置 AutoMagicCalib 微服务和 UI:解析 AMC 代码签出,认证到 NGC,可选下载 VGGT,配置 Docker Compose,启动服务,并验证就绪状态。
先决条件
- 已安装 Docker 和 Docker Compose
- 已配置 NVIDIA Docker Runtime(用于 GPU 支持)
- 磁盘上存在
auto-magic-calib仓库。步骤 0b 会解析当前仓库、DeepStream 的tools/auto-magic-calib、DEEPSTREAM_REPO_ROOT或~/auto-magic-calib;否则在克隆https://github.com/NVIDIA-AI-IOT/auto-magic-calib之前会先询问。 - NGC 账户,并拥有访问 NVIDIA 容器注册表的权限
- Docker 无需
sudo即可运行;继续之前请用docker ps验证。
操作说明
步骤 0:验证 Docker 无需 sudo 即可运行
docker ps
- 如果执行成功 → 继续。
- 如果失败并提示“permission denied” → 用户不在
docker组中。请用户运行:
然后请用户确认sudo usermod -aG docker $USER && newgrp dockerdocker ps正常后再继续。
智能体提示:如果在智能体沙箱中无法运行
docker ps,请用户确认它可以正常运行(例如“您能确认docker ps无需 sudo 即可运行吗?”)然后再继续。
步骤 0b:解析仓库签出
该技能需要 AMC 仓库资产(compose/、示例数据和 models/)。首先解析现有签出;在克隆到 ~/auto-magic-calib 之前要先询问。
REPO_URL="https://github.com/NVIDIA-AI-IOT/auto-magic-calib.git"
DEFAULT_CLONE_DIR="$HOME/auto-magic-calib"
CURRENT_GIT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
is_amc_checkout() {
[ -n "$1" ] \
&& [ -f "$1/README.md" ] \
&& grep -q "AutoMagicCalib" "$1/README.md" 2>/dev/null \
&& [ -f "$1/compose/compose.yml" ] \
&& grep -q "auto-magic-calib-ms" "$1/compose/ms/compose.yml" 2>/dev/null \
&& grep -q "auto-magic-calib-ui" "$1/compose/ui/compose.yml" 2>/dev/null
}
REPO_ROOT=""
for candidate in \
"$CURRENT_GIT_ROOT" \
"${CURRENT_GIT_ROOT:+$CURRENT_GIT_ROOT/tools/auto-magic-calib}" \
"${DEEPSTREAM_REPO_ROOT:+$DEEPSTREAM_REPO_ROOT/tools/auto-magic-calib}" \
"$PWD/tools/auto-magic-calib" \
"$DEFAULT_CLONE_DIR"; do
if is_amc_checkout "$candidate"; then
REPO_ROOT="$candidate"
echo "✓ Using auto-magic-calib checkout: $REPO_ROOT"
break
fi
done
if [ -z "$REPO_ROOT" ]; then
if [ -n "$CURRENT_GIT_ROOT" ] && [ -d "$CURRENT_GIT_ROOT/tools/auto-magic-calib" ]; then
echo "Found $CURRENT_GIT_ROOT/tools/auto-magic-calib, but it is not an initialized AMC checkout."
echo "If running from the DeepStream repository root:"
echo " git submodule update --init tools/auto-magic-calib"
fi
# 这里没有任何可用的签出 — 停下来,使用主机的提问机制向用户请求确认;如果没有,则在聊天中询问并等待。
# 不要从此处静默克隆,也不要克隆到受跟踪的子模块路径。
echo "No usable auto-magic-calib checkout found. Ask the user for confirmation:"
echo " Clone $REPO_URL into $DEFAULT_CLONE_DIR? [y/N]"
echo "On 'y' — run: git clone \"$REPO_URL\" \"$DEFAULT_CLONE_DIR\""
exit 1
fi
cd "$REPO_ROOT"
export REPO_ROOT
echo "REPO_ROOT=$REPO_ROOT"
智能体提示:绝不静默克隆。优先使用已初始化的 DeepStream
tools/auto-magic-calib;不要克隆到该子模块路径上。如果该路径存在但为空,请用户运行git submodule update --init tools/auto-magic-calib。如果提供了其他 AMC 路径,请遵循该路径。
步骤 0c:安装 Python venv(仅限新系统)
在新系统上,pip 和 python3-venv 可能不可用。请先安装它们:
# 为 HuggingFace CLI 创建 venv(优先使用项目本地目录)
REPO_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
HF_VENV="${REPO_DIR}/venv"
python3 -m venv "$HF_VENV" 2>/dev/null || {
echo "ERROR: python3-venv not available." >&2
echo "Install it manually: sudo apt install -y python3-venv python3-pip" >&2
exit 1
}
# 安装 HuggingFace hub(VGGT 下载需要)
"$HF_VENV/bin/pip" install --upgrade pip huggingface_hub
注意:如果已存在带
hf的 venv(检查仓库根目录的venv/bin/hf或~/venv/amc/bin/hf),则跳过此步骤。
步骤 1:登录 NGC
请使用主机的提问机制向用户询问他们的 NGC API 密钥;如果没有,则在聊天中询问并等待。然后运行:
echo "<NGC_API_KEY>" | docker login nvcr.io --username '$oauthtoken' --password-stdin
echo "✓ NGC authentication complete"
步骤 2:下载 VGGT 模型(如果尚未存在)
export REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"
if [ -f "models/vggt/vggt_1B_commercial.pt" ]; then
echo "✓ VGGT model already present"
else
echo "✗ VGGT model not found"
echo "Options:"
echo " 1. Continue without VGGT (AMC only - sufficient for most use cases)"
echo " 2. Download VGGT model (~4.7GB, requires HuggingFace account)"
fi
要下载 VGGT:请用户接受 https://huggingface.co/facebook/VGGT-1B-Commercial 上的许可,并使用主机的提问机制从 https://huggingface.co/settings/tokens 提供读取令牌。通过 HF_TOKEN 传递,以便不会在 ps 输出中暴露:
REPO_DIR="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
cd "$REPO_DIR"
# 找到 HuggingFace CLI 二进制文件(名为 'hf',不是 'huggingface-cli')
HF_BIN="$(find "$REPO_DIR/venv" ~/venv/amc -name hf -type f 2>/dev/null | head -1)"
{ [ -z "$HF_BIN" ] || [ ! -x "$HF_BIN" ]; } && { echo "ERROR: hf binary not found or not executable; install the hf CLI (Step 0c) or set HF_BIN" >&2; exit 1; }
# 不要在命令行使用 --token(会通过 ps/argv 泄漏)。HF CLI
# 会自动从环境中读取 HF_TOKEN。
HF_TOKEN="<HF_TOKEN>" "$HF_BIN" download facebook/VGGT-1B-Commercial \
--local-dir models/vggt/
# 验证
ls -lh models/vggt/vggt_1B_commercial.pt
# 应该显示约 4.7GB 的文件
重要:必须在设置
chown 1000:1000之前下载 —— 当前用户在下载期间需要写权限。请在步骤 4 下载完成后设置权限。
步骤 3:配置 Compose 环境变量
Compose 环境文件控制端口和路径。在启动前更新它:
cd $REPO_ROOT/compose
# 查找可用的后端端口 (8000-8009)
for port in {8000..8009}; do
if ! lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
MS_PORT=$port
echo "Using backend port: $MS_PORT"
break
fi
done
[ -z "$MS_PORT" ] && { echo "ERROR: no free backend port in 8000-8009; free one or widen the range." >&2; exit 1; }
# 查找可用的 UI 端口 (5000-5009)
for port in {5000..5009}; do
if ! lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
UI_PORT=$port
echo "Using UI port: $UI_PORT"
break
fi
done
[ -z "$UI_PORT" ] && { echo "ERROR: no free UI port in 5000-5009; free one or widen the range." >&2; exit 1; }
# 获取主机 IP
HOST_IP=$(hostname -I | awk '{print $1}')
echo "Host IP: $HOST_IP"
# 保留现有键并限制 Compose 环境文件的权限。
COMPOSE_ENV_BASENAME="env"
ENV_FILE=".${COMPOSE_ENV_BASENAME}"
if [ -f "$ENV_FILE" ]; then
BACKUP="${ENV_FILE}.bak.$(date +%s)"
cp "$ENV_FILE" "$BACKUP"
chmod 600 "$BACKUP"
fi
touch "$ENV_FILE"
chmod 600 "$ENV_FILE"
set_env_key() {
local k="$1" v="$2"
if grep -qE "^${k}=" "$ENV_FILE"; then
sed -i "s|^${k}=.*|${k}=${v}|" "$ENV_FILE"
else
echo "${k}=${v}" >> "$ENV_FILE"
fi
}
set_env_key AUTO_MAGIC_CALIB_MS_PORT "${MS_PORT}"
set_env_key AUTO_MAGIC_CALIB_UI_PORT "${UI_PORT}"
set_env_key PROJECT_DIR "../../projects"
set_env_key MODEL_DIR "../../models"
set_env_key HOST_IP "${HOST_IP}"
# 让带时间戳的 Compose 环境备份远离 git。
GITIGNORE="$REPO_ROOT/.gitignore"
touch "$GITIGNORE"
BACKUP_PATTERN="compose/${ENV_FILE}.bak.*"
grep -qxF "$BACKUP_PATTERN" "$GITIGNORE" || echo "$BACKUP_PATTERN" >> "$GITIGNORE"
echo "✓ Compose environment file updated"
cat "$ENV_FILE"
重要:HOST_IP 必须是机器的网络 IP(不是 localhost),这样 UI 容器才能从浏览器访问后端。
可选:仅当 VGGT 模型挂载在非默认容器路径时,设置 VGGT_MODEL_PATH;默认为 MS 容器内的 /tmp/vggt_model/vggt_1B_commercial.pt。
RTSP 标定可选:启动后请使用 skills/amc-run-rtsp-calibration/SKILL.md。该技能会在需要时验证 VIOS 可达性,并使用临时 compose override 重新启动微服务,导出 VIOS_BASE_URL,而不修改已检查的 compose 文件。
步骤 4:设置目录权限
容器以 UID/GID 1000 运行。projects 和 models 目录必须归该 UID 所有,容器才能正常读写:
cd "$REPO_ROOT"
# 如果 projects 目录不存在则创建
mkdir -p projects
# 设置所有权(容器写入标定输出所必需)。
# 一定要在 VGGT 下载完成后再执行(下载期间当前用户需要写权限)。
# 在执行 sudo chown 前需获得用户明确确认 — 它会递归更改
# $REPO_ROOT/projects 和 $REPO_ROOT/models 的所有者为 UID/GID 1000。
[ -d projects ] && [ -d models ] || {
echo "ERROR: expected projects/ and models/ under $REPO_ROOT" >&2; exit 1;
}
echo "About to chown -R 1000:1000 on:"
echo " $REPO_ROOT/projects"
echo " $REPO_ROOT/models"
echo "(required because containers run as UID 1000). Confirm before proceeding."
sudo chown 1000:1000 -R projects
sudo chown 1000:1000 -R models
echo "✓ Permissions set"
步骤 5:启动服务
在拉取之前,快速失败:如果步骤 1 中认证的 NGC 密钥实际上无法访问某个发布镜像,则 docker compose up 会在部分工作完成后以 401/403 中止。
cd $REPO_ROOT/compose
# 快速失败镜像访问检查:确认 NGC 密钥可以访问所有发布的镜像,
# 然后再进行拉取。`docker manifest inspect` 检查注册表的访问权限而不下载层。
# 镜像列表从解析后的 compose 中读取,因此会自动跟踪发布标签。
IMAGES=$(docker compose config --images | sort -u)
[ -z "$IMAGES" ] && { echo "ERROR: no images resolved from compose — check the Compose environment settings and chosen profile." >&2; exit 1; }
for img in $IMAGES; do
echo "Checking access: $img"
if ! docker manifest inspect "$img" >/dev/null 2>&1; then
echo "NGC login succeeded, but this key cannot access the required image:" >&2
echo " $img" >&2
echo "Provide an NGC key with access to this image's namespace, then re-run Step 1 (login) and retry." >&2
exit 1
fi
done
# 启动所有服务(首次运行时会自动拉取镜像)
docker compose up -d
# 检查容器是否正在运行
docker compose ps
确切的镜像标签随版本而变化;请从当前的 compose 文件中读取,而不是硬编码版本。
步骤 6:验证服务是否正在运行
# 从 Compose 环境文件读取端口。
COMPOSE_ENV_BASENAME="env"
COMPOSE_ENV_FILE="$REPO_ROOT/compose/.${COMPOSE_ENV_BASENAME}"
MS_PORT=$(grep AUTO_MAGIC_CALIB_MS_PORT "$COMPOSE_ENV_FILE" | cut -d= -f2)
UI_PORT=$(grep AUTO_MAGIC_CALIB_UI_PORT "$COMPOSE_ENV_FILE" | cut -d= -f2)
HOST_IP=$(grep HOST_IP "$COMPOSE_ENV_FILE" | cut -d= -f2)
# 等待微服务就绪。冷拉取镜像或首次启动可能需要
# `docker compose up -d` 返回后额外的时间。
READY_URL="http://localhost:${MS_PORT}/v1/ready"
echo "Waiting for microservice readiness at ${READY_URL} ..."
ready_response=""
for attempt in $(seq 1 24); do
if ready_response=$(curl -fsS --max-time 5 "${READY_URL}" 2>/dev/null) && \
echo "${ready_response}" | grep -q '"code"[[:space:]]*:[[:space:]]*0'; then
echo "Microservice ready: ${ready_response}"
break
fi
if [ "${attempt}" -lt 24 ]; then
printf " [%02d/24] Microservice not ready yet; retrying in 5s...
" "${attempt}"
sleep 5
fi
done
if ! echo "${ready_response}" | grep -q '"code"[[:space:]]*:[[:space:]]*0'; then
echo "ERROR: microservice did not report ready within 120 seconds: ${READY_URL}" >&2
echo "Check status and logs:" >&2
echo " cd ${REPO_ROOT}/compose && docker compose ps" >&2
echo " cd ${REPO_ROOT}/compose && docker compose logs auto-magic-calib-ms" >&2
exit 1
fi
# 检查 UI 是否在提供页面
UI_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "http://localhost:${UI_PORT}")
if [ "${UI_STATUS}" != "200" ]; then
echo "ERROR: Web UI returned HTTP ${UI_STATUS}; check docker compose ps and UI logs." >&2
exit 1
fi
echo "Web UI ready: HTTP ${UI_STATUS}"
echo "Microservice: http://${HOST_IP}:${MS_PORT}"
echo "Web UI: http://${HOST_IP}:${UI_PORT}"
成功标准
docker compose ps显示 MS 和 UI 容器为Up;MS 应为 healthy。/v1/ready返回code:0,并且步骤 6 打印微服务和 UI 的 URL。- 浏览器通过
http://<HOST_IP>:<AUTO_MAGIC_CALIB_UI_PORT>可访问。 - 项目会持久化在
$REPO_ROOT/projects/下。
故障排查
| 问题 | 修复方法 |
|---|---|
| Docker 权限被拒绝 | 请用户运行 sudo usermod -aG docker $USER && newgrp docker,然后重试 docker ps。 |
docker login 被拒绝 |
请求一个当前的 NGC 密钥并重新登录。 |
| 所需镜像不可访问 | 密钥缺少镜像命名空间访问权限;请提供一个有权限的密钥,然后重试步骤 1 和步骤 5。 |
python3 -m venv、pip 或 hf 缺失 |
安装 python3-venv/python3-pip;HF 二进制文件名为 hf。 |
| VGGT 权限错误 | 在 chown 1000:1000 之前下载 VGGT;恢复时,将 models/ 的所有者恢复为当前用户并重新下载。 |
| 端口被占用 | 在 8000-8009 选择一个空闲的 MS 端口,在 5000-5009 选择一个空闲的 UI 端口,然后更新 Compose 环境文件。 |
| 就绪超时或容器退出 | 运行 cd $REPO_ROOT/compose && docker compose ps 并检查 docker compose logs auto-magic-calib-ms。 |
| 项目/模型权限被拒绝 | 仅对 projects/ 或 models/ 重新执行步骤 4。 |
| UI 无法访问后端 | 检查 Compose 环境文件中的 HOST_IP 是否为机器网络 IP,而不是 localhost。 |
| GPU 不可用 | 用 docker run --rm --runtime=nvidia --gpus all ubuntu:20.04 nvidia-smi 验证 NVIDIA runtime。 |
常用修复:
cd $REPO_ROOT/compose
# 查看日志
docker compose logs -f
# 查看特定服务的日志
docker compose logs -f auto-magic-calib-ms
# 重启所有服务
docker compose restart
# 停止并移除容器
docker compose down
# 更新 Compose 环境设置并重新启动
docker compose up -d
停止服务
cd $REPO_ROOT/compose
# 停止所有服务(容器移除,数据保留)
docker compose down
# 停止并移除卷
docker compose down -v
相关技能
skills/amc-run-sample-calibration/SKILL.md- 使用自带的示例数据集对已运行的堆栈进行健康检查skills/amc-run-video-calibration/SKILL.md- 通过 REST API 使用您自己预先录制的 MP4 进行标定skills/amc-run-rtsp-calibration/SKILL.md- 通过 VIOS 采集对实时 RTSP 流进行标定
<!-- signing marker -->