关于 vss-deploy-video-embedding
用于部署和运维 VSS 视频嵌入微服务,并通过 REST API 生成文本或视频嵌入。它支持上传文件、URL 和实时 RTSP 流,并提供与 Redis、Kafka 及 OpenTelemetry 的可选连接配置。
主要功能
- 01通过 Docker Compose 部署服务
- 02生成文本和视频嵌入
- 03处理上传文件、URL 与 RTSP 流
- 04支持分块嵌入的 SSE 输出
- 05检查就绪状态、指标和资产统计
适用场景
- 01为视频搜索生成文本嵌入
- 02为上传的视频文件生成嵌入
- 03为实时 RTSP 流生成嵌入
- 04排查模型下载、GPU 或流重连问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nvidia/ skills --skill vss-deploy-video-embedding安装后在 Claude Code 中输入/vss-deploy-video-embedding确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
BENCHMARK.mdskill-card.mdskill.oms.sigevals/evals.jsonstandalone_deploy.jsonreferences/deploy-vss-deploy-video-embedding.mdenvironment.mdintegrate-vss-deploy-video-embedding.mdREADME.mdrest-api.mdtroubleshooting.md详细介绍
VSS 视频嵌入(RT-Embed)
在以下情况下使用此技能:
- 从 Docker Compose 文件部署 VSS 视频嵌入微服务。
- 使用 Cosmos-Embed1-448p 模型生成文本或视频嵌入。
- 为上传的文件、HTTP/S3/文件/数据 URL 或实时 RTSP 流生成嵌入。
- 将服务接入 VSS 部署,并与 Redis、Kafka 和 OpenTelemetry 配合使用。
- 排查就绪状态、模型下载、GPU 或流重新连接故障。
触发短语: vss-deploy-video-embedding、RT-Embed、rtvi-embed、video embedding service、Cosmos-Embed1、embed live stream、embed video file、generate video embeddings、text embedding for video search。
服务概览
- VSS 3.2 GA 技能:
vss-deploy-video-embedding。 - 旧版 3.1 名称: RT-Embed。
- Compose 服务:
rtvi-embed。 - 容器名称:
vss-rtvi-embed。 - 镜像:
nvcr.io/nvidia/vss-core/vss-rt-embed(使用RTVI_EMBED_IMAGE覆盖)。 - 默认标签:
3.2.1(使用RTVI_EMBED_TAG覆盖)。 - 配置文件:
bp_developer_search_2d。 - 容器端口:
8000(主机端口为${RTVI_EMBED_PORT})。 - 默认模型: 来自
nvidia/Cosmos-Embed1-448p的cosmos-embed1-448p。 - 健康检查端点:
GET /v1/ready。 - 健康检查启动宽限期: 首次启动时为
1200s(20 分钟)。
前置条件
启动服务之前:
- 已安装 NVIDIA 驱动和 NVIDIA Container Toolkit;默认运行时设为
nvidia。 - Docker Engine 和 Docker Compose 插件版本足够新,支持
${VAR:+value}条件卷替换。 - 已使用
$oauthtoken和有效的 NGC API 密钥完成docker login nvcr.io。 - 主机环境至少提供:
RTVI_EMBED_PORT、VSS_DATA_DIR、NGC_API_KEY;还可选提供HF_TOKEN,以避免下载 Cosmos-Embed1 权重时遇到 Hugging Face 429 速率限制错误。 - 为持久化缓存预留足够的磁盘空间:
rtvi-hf-cache、rtvi-ngc-model-cache、rtvi-triton-model-repo(数 GB)。
完整的前置条件列表请参阅 references/deploy-vss-deploy-video-embedding.md,变量矩阵请参阅 references/environment.md。
部署
要独立部署 RT-Embed,请在服务目录中操作:
cd "{{repo_root}}/deploy/docker/services/rtvi/rtvi-embed"
独立部署时,不要使用 /vss-deploy-profile 或 scripts/dev-profile.sh。
对于 Agent 驱动的验证,绝不要让 sudo 进行交互式提示。在执行任何需要特权的所有权更改或 Docker 操作之前,请使用
references/deploy-vss-deploy-video-embedding.md
和 references/troubleshooting.md 中的非交互式防护措施:优先使用普通的
docker;否则使用 sudo -n docker;如果 sudo -n 失败,请停止操作,并向主机所有者提供准确的
手动命令,而不是重试交互式 sudo 或降低权限要求。
在运行 docker compose up 之前,设置最精简的独立环境。如果 sudo -n chown
失败,请在运行 docker compose up 之前停止,并请主机所有者运行打印出的
命令。
export RTVI_EMBED_PORT=8017
export VSS_DATA_DIR="${VSS_DATA_DIR:-$(pwd)/.standalone-data}"
export NGC_API_KEY="<your-ngc-api-key>"
export HOST_IP="$(hostname -I | awk '{print $1}')"
export HF_TOKEN="${HF_TOKEN:-}" # optional, but recommended to avoid HF 429s
export RTVI_EMBED_KAFKA_ENABLED=false
export ENABLE_REDIS_ERROR_MESSAGES=false
# Prepare VST clip-storage host dir; use `sudo -n` for ownership fixes.
CLIP_STORAGE_DIR="${VSS_DATA_DIR}/data_log/vst/clip_storage"
mkdir -p "$CLIP_STORAGE_DIR"
if ! sudo -n chown -R 1001:1001 "$CLIP_STORAGE_DIR"; then
echo "ERROR: passwordless sudo is unavailable for host-path ownership." >&2
echo "Ask the host owner to run: sudo chown -R 1001:1001 \"$CLIP_STORAGE_DIR\"" >&2
echo "Do not work around this with chmod 777 or world-writable permissions." >&2
return 1 2>/dev/null || exit 1
fi
这样可以避免在未设置 VSS_DATA_DIR 时从文件系统根目录挂载 /data_log/vst/clip_storage,并防止独立模式下因缺少 Kafka/Redis 对等服务而导致启动停滞。
# Bring up the service under the required Compose profile.
docker compose -f rtvi-embed-docker-compose.yml \
--profile bp_developer_search_2d up -d rtvi-embed
如果 Docker 需要更高权限,请使用 sudo -n docker compose ...;如果 sudo -n 提示需要密码,请立即停止。
# Watch logs while the model downloads and Triton repo builds.
docker compose -f rtvi-embed-docker-compose.yml logs -f rtvi-embed
首次启动时,下载 Cosmos-Embed1 并构建 Triton 模型仓库可能需要 20 分钟。首次启动时不要缩短健康检查的 start_period: 1200s,否则容器仍在预热时就会被标记为不健康。
验证
BASE_URL="http://localhost:${RTVI_EMBED_PORT}"
curl -fsS "$BASE_URL/v1/ready" # 200 when warm.
curl -fsS "$BASE_URL/v1/ready?detailed=true" # Component-level status.
curl -fsS "$BASE_URL/v1/version"
MODELS_JSON=$(curl -fsS "$BASE_URL/v1/models")
echo "$MODELS_JSON" # Confirms cosmos-embed1-448p is loaded.
MODEL_ID="$(echo "$MODELS_JSON" | jq -r '.data[0].id // empty')"
test -n "$MODEL_ID" || { echo "ERROR: /v1/models has no model id — wait until /v1/ready is 200" >&2; exit 1; }
下方调用 API 的各节会复用此部分中的 $BASE_URL 和 $MODEL_ID。
常见操作
从上传的文件生成视频嵌入
FILE_ID=$(curl -fsS -X POST "$BASE_URL/v1/files" \
-F purpose=vision \
-F media_type=video \
-F file=@/path/to/clip.mp4 | jq -r .id)
curl -fsS -X POST "$BASE_URL/v1/generate_video_embeddings" \
-H "Content-Type: application/json" \
-d "{
\"id\": \"$FILE_ID\",
\"model\": \"$MODEL_ID\",
\"chunk_duration\": 60,
\"chunk_overlap_duration\": 10
}"
生成文本嵌入(用于文本到视频搜索)
curl -fsS -X POST "$BASE_URL/v1/generate_text_embeddings" \
-H "Content-Type: application/json" \
-d "{\"text_input\":\"a forklift moving pallets\",\"model\":\"${MODEL_ID}\"}"
嵌入实时 RTSP 流
实时流必须设置 stream: true,且 chunk_duration > 0。同步调用会返回 400 BadParameters: "Only streaming output is supported for live-streams";streams/add 返回的 chunk_duration: 0 只是占位值——必须在嵌入请求中覆盖,否则会收到 400 BadParameter: "chunk_duration must be greater than 0"。
POST /v1/streams/add 不会根据 liveStreamUrl 去重——两次提交相同的 URL 会生成两个不同的 stream_id。添加前,请调用 GET /v1/streams/get-stream-info,并复用该 URL 已有的注册信息,以避免产生孤立条目。
STREAM_ID=$(curl -fsS -X POST "$BASE_URL/v1/streams/add" \
-H "Content-Type: application/json" \
-d '{"streams":[{"liveStreamUrl":"rtsp://host:port/live/video","description":"camera-001"}]}' \
| jq -r '.results[0].id')
curl -N -X POST "$BASE_URL/v1/generate_video_embeddings" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d "{
\"id\": \"$STREAM_ID\",
\"model\": \"$MODEL_ID\",
\"stream\": true,
\"chunk_duration\": 10,
\"chunk_overlap_duration\": 2
}"
# List registered live streams (use this to recover stream_ids across sessions).
curl -fsS "$BASE_URL/v1/streams/get-stream-info"
# Stop embedding for the stream when done (terminates SSE with data: [DONE]).
curl -fsS -X DELETE "$BASE_URL/v1/generate_video_embeddings/$STREAM_ID"
完整的端点目录、SSE 流式传输和单流控制面模式,请参阅 references/rest-api.md。
日志、指标和状态
docker compose -f rtvi-embed-docker-compose.yml ps
docker compose -f rtvi-embed-docker-compose.yml logs -f rtvi-embed
docker stats vss-rtvi-embed
curl -fsS "$BASE_URL/v1/metrics" # Prometheus.
curl -fsS "$BASE_URL/v1/assets/stats" # Asset storage counts and TTL.
如果 RTVI_EMBED_LOG_DIR 绑定到主机目录,主机上的 /opt/nvidia/rtvi/log/rtvi/ 也可访问日志文件。
集成接口
- 输入:
:${RTVI_EMBED_PORT}上的 REST API(POST /v1/files、POST /v1/generate_text_embeddings、POST /v1/generate_video_embeddings、实时流控制端点)。 - 输出: 同步 REST 响应;分块视频嵌入的可选 SSE;启用 Kafka 时,在
RTVI_EMBED_KAFKA_TOPIC(容器变量KAFKA_TOPIC)和RTVI_EMBED_ERROR_MESSAGE_TOPIC(容器变量ERROR_MESSAGE_TOPIC)指定的主题上发送可选 Kafka 消息(主机变量:RTVI_EMBED_KAFKA_ENABLED=true,Compose 会将其映射为容器变量KAFKA_ENABLED)。 - 可选协作服务: Redis(
ENABLE_REDIS_ERROR_MESSAGES=true)、Kafka(主机变量RTVI_EMBED_KAFKA_ENABLED=true→ 容器变量KAFKA_ENABLED)、OpenTelemetry 收集器(主机变量RTVI_EMBED_ENABLE_OTEL_MONITORING=true→ 容器变量ENABLE_OTEL_MONITORING)。
references/integrate-vss-deploy-video-embedding.md 介绍了完整的集成契约。
错误处理
API 失败时会返回包含 code 和 message 字段的 JSON:
{
"code": "BadParameter",
"message": "chunk_duration must be greater than 0"
}
Pydantic / OpenAPI 验证失败时会返回 HTTP 422,其中包含 code: "InvalidParameters" 和字段级 message。
| Code | 含义 | 常见原因 |
|---|---|---|
| 400 | 错误请求 | 缺少 text_input;未知的 file_id / stream_id / model;调用实时流时未设置 stream: true;实时流嵌入请求中 chunk_duration: 0;chunk_overlap_duration >= chunk_duration |
| 401 | 未授权 | 部署启用身份验证时,缺少或提供了无效的 Authorization: Bearer <token> |
| 403 | 禁止访问 | 已禁用 file:// URL(未设置 FILE_URL_ALLOWED_DIRS),或解析后的路径不在允许列表中(code: "Forbidden") |
| 409 | 冲突 | 文件正在使用时调用 DELETE /v1/files/{file_id}(ResourceInUse);另一客户端已连接到同一实时流(Conflict) |
| 413 | 请求载荷过大 | 上传的文件或解码后的 data: URI 超出服务端大小限制 |
| 422 | 无法处理的实体 | 架构验证失败 — UUID 格式错误、多部分字段类型错误、枚举值无效;受支持方案的 URL 格式无效 |
| 429 | 请求过于频繁 | 请求速率超限 — 使用指数退避重试 |
| 500 | 内部服务器错误 | 意外的推理或 I/O 故障 — 检查 docker compose -f rtvi-embed-docker-compose.yml logs -f rtvi-embed |
| 503 | 服务不可用 | /v1/ready 仍在预热(模型下载 / Triton 仓库构建);嵌入端点正忙于处理另一个文件或文本查询;实时流数量达到上限;推理期间 CUDA OOM |
首次启动期间,/v1/ready 返回 503 是预期情况,直到 Cosmos-Embed1 完成下载且 Triton 模型仓库构建完成(最长约 20 分钟)。在健康检查的 start_period: 1200s 结束之前,请勿将其视为应用程序错误。
嵌入端点返回 503 且消息为 "Server is busy processing another file or text" 或 "Server is busy processing another file / live-stream.",表示该服务一次仅处理一个同步嵌入任务 — 使用退避策略重试,或将工作分片到多个实例。
有关端点特定限制(实时流 SSE 要求、URL 方案、响应架构),请参阅 references/rest-api.md。有关 Compose 启动、缓存和权限故障,请参阅 references/troubleshooting.md。
故障排查
有关常见故障模式及解决方法,请参阅 references/troubleshooting.md。常见问题:
/v1/ready一直返回 503 → 检查是否缺少NGC_API_KEY、首次启动下载模型期间是否遇到 Hugging Face 429 速率限制错误(设置HF_TOKEN可避免),或启用相关标志时 Redis/Kafka 节点是否无法访问。- 前 20 分钟内健康检查状态反复变为不健康 → 恢复
start_period: 1200s。 - 绑定挂载的缓存目录出现权限错误 → 在主机路径上运行
sudo -n chown -R 1001:1001;如果无法使用免密 sudo,请让主机所有者运行打印出的命令(不要使用chmod 777)。 - 部署期间
sudo提示输入密码 → 使用sudo -n并快速失败;请参阅references/troubleshooting.md;切勿在 Agent 会话中改用交互式 sudo 重试。
升级与回滚
固定 RTVI_EMBED_IMAGE / RTVI_EMBED_TAG,拉取镜像,使用 --profile bp_developer_search_2d 重新创建,并等待 /v1/ready 就绪后再切换。命名卷会在镜像切换期间保留。
完整步骤:升级与回滚。
拆除
使用 docker compose -f rtvi-embed-docker-compose.yml down 停止独立堆栈。仅当你打算销毁命名模型缓存时,才使用 down -v。
完整步骤及缓存警告:拆除。
参考资料
| 文件 | 何时阅读 |
|---|---|
| references/README.md | 所有参考文件的目录。 |
| references/deploy-vss-deploy-video-embedding.md | Vision Agent 部署构建参考:镜像、GPU、存储、启动、先决条件和已知问题。 |
| references/integrate-vss-deploy-video-embedding.md | Vision Agent 集成构建参考:对等方、输入/输出、环境变量、网络和 Compose 示例片段。 |
| references/rest-api.md | 完整的 REST 端点目录,包含文件上传、视频/文本嵌入、实时流和健康状态/指标的 curl 示例。 |
| references/environment.md | 完整的环境变量列表,包括主机到容器的重命名和敏感信息变量。 |
| references/troubleshooting.md | 针对启动、模型/缓存、运行时和可观测性问题的运维诊断。 |