关于 serving-llms-on-instinct
用于指导在 AMD Instinct GPU 上部署 vLLM 端点的 skill,面向部署运维人员。它涵盖 GPU 检测、环境验证、模型配置与显存估算,并可指导在本地或远程主机启动和验证服务。
主要功能
- 01本地或通过 SSH 检测 GPU
- 02验证运行环境
- 03读取模型配方与 GPU 覆盖配置
- 04估算显存和张量并行需求
- 05启动并检查 vLLM 端点
适用场景
- 01为 AMD Instinct GPU 准备模型服务命令
- 02检查模型是否适配可用显存
- 03在远程 GPU 主机启动并验证端点
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ amd/ skills --skill serving-llms-on-instinct安装后在 Claude Code 中输入/serving-llms-on-instinct确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
reference.mdskill-card.mddata/blacklist.jsongpu_overrides.jsonevals/evals.jsonhooks.pymachine.ymlscripts/detect.pyestimate_vram.pysync_recipes.pyvalidate.py详细介绍
在 AMD Instinct 上提供 LLM 服务
在 AMD Instinct GPU 硬件上运行 vLLM 端点。
前提条件
- 在 GPU 主机上安装 ROCm 驱动和
amd-smi - Docker 正在运行且可访问(使用
docker ps检查) - GPU 主机上存在
/dev/kfd和/dev/dri HF_TOKEN环境变量中设置了 HuggingFace 令牌(门控模型需要;Qwen3 或 Gemma 不需要)。对于门控模型(Llama 3.2、Gemma 等),HF 令牌必须属于已在huggingface.co/<model_id>接受该模型许可的账户。有效令牌若未接受许可,将报错“Engine core initialization failed”,且错误信息不明确。- 对于远程 GPU:已配置 SSH 密钥访问(运行
ssh <user>@<host>时不应提示输入密码)。如果只能使用密码访问,请先设置密钥:ssh-copy-id <user>@<host>
数据文件
直接读取这些文件以获取模型和 GPU 配置:
-
data/recipes_cache.json—— 从 vllm-project/recipes 同步的模型配置。每个models.<HF_ID>.recipe条目都包含完整的配方,其中有model.base_args、model.base_env、features.tool_calling.args、features.reasoning.args、hardware_overrides.amd.extra_args、hardware_overrides.amd.extra_env。 顶层的docker_image字段包含最新解析出的 vLLM ROCm 镜像。 -
data/gpu_overrides.json—— GPU 专属配置。包含docker_flags(所有 AMD Instinct GPU 都必须设置)、以 gfx_version 为键的gpu_configs(含env_defaults和workarounds),以及适用于尚未收录到 vLLM 配方中的模型的legacy_models。 -
data/blacklist.json—— vLLM 配方中无法作为 LLM 端点提供服务的模型。包括扩散/图像/音频生成模型、嵌入模型、重排模型、需要音频管线的 ASR 模型,以及需要尚未发布的 vLLM nightly 版本的模型。尝试提供模型服务前,请先检查此文件。如果用户请求的模型在黑名单中,请说明无法运行的原因并推荐替代方案。
如果用户未指定模型,默认使用 Qwen/Qwen3.5-9B:采用 MTP 的稠密多模态模型,Apache 2.0 许可证(无需 HF 令牌),可在单张 GPU 上运行,具备出色的推理和工具调用能力。
步骤 1:检测 GPU
python3 scripts/detect.py
# Remote:
python3 scripts/detect.py --host user@hostname
返回包含 gfx_version、vram_gb、gpu_count、rocm_version 的 JSON。
| gfx_version | 硬件 | VRAM |
|---|---|---|
| gfx950 | MI350X / MI355X | 288 GB HBM3E |
| gfx942 | MI300X(192 GB)/ MI325X(256 GB)/ MI300A(128 GB) | 不定 |
如果 gfx_version 为 unknown:amd-smi 已运行,但未找到 GPU。请检查
lsmod | grep amdgpu。
步骤 2:验证环境
python3 scripts/validate.py --auto-fix
# Remote:
python3 scripts/validate.py --auto-fix --host user@hostname
返回包含 ready(布尔值)、errors、warnings、fixes_applied 的 JSON。
如果 ready 为 false,请勿继续。
步骤 3:刷新配方(如已过期)
检查 data/recipes_cache.json 中的 fetched_at。如果文件缺失或距今超过 24 小时,请刷新:
python3 scripts/sync_recipes.py
此操作会从 GitHub 浅克隆 vllm-project/recipes,并从 Docker Hub 获取最新的 Docker 标签。耗时约 10 秒。如果失败,现有缓存仍可使用。
步骤 4:构建 Docker 命令
直接读取 data/recipes_cache.json 和 data/gpu_overrides.json。
组合以下内容来构建 Docker 命令:
gpu_overrides.json > docker_flags中的 Docker 标志(所有 AMD GPU 均为必需项)- HF 缓存挂载:
-v ~/.cache/huggingface:/root/.cache/huggingface(如果主机上存在共享模型缓存目录,请检查models--*目录是在缓存根目录下,还是在hub/子目录中,然后相应地挂载到/root/.cache/huggingface或/root/.cache/huggingface/hub) - 端口:
-p <port>:<port>(默认值为 8000) - 环境变量:将
gpu_configs.<gfx_version>.env_defaults与配方中的model.base_env和hardware_overrides.amd.extra_env合并。 始终添加--env HF_TOKEN=${HF_TOKEN}。 - Docker 镜像:使用
recipes_cache.json顶层的docker_image(除非模型需要固定版本的镜像,例如 GLM-4.5 需要v0.15.1)。 如果用户指定了 Docker 镜像版本,请对照配方中的model.min_vllm_version检查。如果镜像版本较旧,请发出警告——模型可能会在启动时因含义不明的“Engine core initialization failed”错误而崩溃。 - 模型 ID:
--model <HF_ID> - vLLM 参数:合并配方中的
model.base_args+hardware_overrides.amd.extra_args+features.tool_calling.args+features.reasoning.args。如果尚未添加,请添加--enable-auto-tool-choice。 对于多 GPU,添加--tensor-parallel-size N(请参阅下文的 VRAM 估算)。 对于多 GPU 上运行的 MoE 模型,还需添加--distributed-executor-backend mp。 - 端口参数:
--port <port>
如果 recipes_cache.json 中没有完全匹配的模型 ID,请去掉日期/版本后缀,检查是否存在基础模型匹配项(例如,Kimi-K2-Instruct 匹配
Kimi-K2-Instruct-0905)。如果找到,请使用基础模型的配方。
如果没有匹配的配方,请检查 gpu_overrides.json 中的 legacy_models。如果其中也没有,则使用通用配置:
--enable-auto-tool-choice --trust-remote-code --tool-call-parser hermes。
精度变体选择: 配方可能提供多个变体(默认、fp8、
nvfp4)。选择变体前,请检查
gpu_overrides.json 中的 gpu_configs.<gfx_version>.precision.native。在 gfx942(MI300X)上,只有
bf16、fp16、fp8_fnuz 和 int8 是硬件原生支持的。MXFP4 和 NVFP4
计算采用模拟方式(矩阵乘期间反量化为 BF16),但权重仍以压缩形式保存在 VRAM 中,因此量化模型仍可在更少的内存中运行。
在 gfx950(MI350X)上,MXFP4 是硬件原生支持的。
VRAM 估算和适配检查: 构造 Docker 命令前,请估算模型是否能在可用硬件上运行:
python3 scripts/estimate_vram.py --model-id <HF_ID> --vram-gb <per_gpu_vram> --tp <N>
此操作会查询 HuggingFace Hub API(不会下载模型),并返回包含以下内容的 JSON:
weight_memory_gb——权重总大小kv_cache_bytes_per_token——BF16 下每个 token 的 KV 缓存开销fit.weights_fit——权重是否能在给定的 TP 下装入显存fit.recommended_max_model_len——GPU 可提供服务的最大上下文长度fit.context_limited——如果 KV 缓存导致上下文长度低于模型原生最大值,则为 truefit.min_tp_required——所需的最小 TP(仅当权重无法装入显存时显示)
了解开销: 该脚本会为 vLLM 的运行时开销预留约 4 GB
(激活值分析、HIP 图捕获、内部缓冲区)。启动期间,vLLM 会运行一次分析前向传递,以测量峰值激活值,然后捕获 HIP 图以优化解码。此启动峰值高于稳定运行时的峰值。remaining_for_kv_gb 字段反映了扣除权重和此开销后剩余的空间。
使用 remaining_for_kv_gb 来判断:
remaining_for_kv_gb >= 6:可以安全运行。如果context_limited: true, 在 vLLM 参数中添加--max-model-len <recommended_max_model_len>。 如果用户需要更长的上下文,提及 FP8 KV 缓存选项(--kv-cache-dtype fp8);fit.max_seq_len_fp8_kv会显示提升幅度。remaining_for_kv_gb在 2 到 6 之间:余量紧张,但值得尝试。正常启动。 如果 vLLM 在 HIP 图捕获期间 OOM(检查容器日志中是否在 "capturing CUDA/HIP graphs" 之后出现 "out of memory"),请在 vLLM 参数中添加--enforce-eager后重试。此操作会跳过图捕获并释放 1-2 GB。唯一的代价是 解码延迟略有增加。remaining_for_kv_gb < 2:余量过于紧张,可能会在激活分析步骤中 OOM。 不要尝试。- 多块 GPU 且
weights_fit: false:使用--tp <min_tp_required>重新运行, 并再次检查。 weights_fit: false,且 GPU 数量不足:按以下顺序查找量化替代版本: a. 配方变体:配方可能提供fp8或mxfp4变体,其model_id指向不同的量化检查点。 b. 同一提供方:许多提供方会随基础模型一同发布量化版本(例如 Qwen 提供的Qwen/Qwen3.5-122B-FP8)。在 HuggingFace 上搜索<provider>/<model-name>, 并使用 FP8/GPTQ/AWQ 后缀。 c. AMD 量化模型:AMD 的 Quark 团队会在 HuggingFace 的amd/组织下 发布量化模型(例如amd/Kimi-K2-Instruct-w-mxfp4-a-fp8)。 搜索amd/<model-name>变体。 对量化模型 ID 运行estimate_vram.py,确认显存足够,然后改用该模型 ID。- 仍不满足要求:告知用户该模型所需的 VRAM 超出可用容量,并建议改用更小的模型 或多 GPU 硬件。不要尝试启动。
Docker 命令模板:
docker run -d --name vllm-<model-slug> \
<docker_flags> \
-v <hf_cache_mount> \
-p <port>:<port> \
--env <key>=<value> (for each env var) \
--env HF_TOKEN=${HF_TOKEN} \
<docker_image> \
--model <model_id> \
<vllm_args> \
--port <port>
步骤 5:向用户确认
启动前,向用户展示摘要并请其确认:
- 模型:完整的 HuggingFace ID(例如
Qwen/Qwen3.5-122B-Instruct) - 精度:所用变体(例如 BF16、FP8)及原因
- 权重显存:来自 estimate_vram.py 的结果
- GPU:检测到的硬件和 VRAM
- TP:张量并行度(1、2、4、8)
- 上下文:可实现的最大上下文长度(以及是否受限)
- 端口:端点将使用的端口
如果选择了量化替代版本(步骤 4 的适配性检查),请说明原始模型不适配, 并指出所用的替代版本。
等待用户确认后再继续。
第 6 步:启动并验证
启动前,检查端口冲突:
ss -tlnp 2>/dev/null | grep ':<port> '
如果该端口上有 Docker 容器,请使用 docker rm -f <name> 停止它。
运行 Docker 命令。然后使用此循环轮询健康状态:
while docker inspect --format='{{.State.Running}}' <container_name> 2>/dev/null | grep -q true; do
curl -sf http://localhost:<port>/health && echo "READY" && exit 0
sleep 60
done
echo "FAILED -- container exited"
加载期间出现 503 属于正常情况。根据模型大小(来自 hf-mem 的权重内存)选择轮询策略:
- 小型模型(权重 < 100 GB):将轮询作为阻塞命令运行,并将 Bash 工具的
timeout设为 600000(10 分钟)。大多数已缓存的模型会在 2-5 分钟内就绪。 - 大型模型(权重 >= 100 GB):运行轮询时将 Bash 工具的
run_in_background设为true。然后使用TaskOutput,设置block: true和timeout: 600000,每次检查最多等待 10 分钟。如果任务在这之后仍在运行,请使用相同参数再次调用TaskOutput。这样每等待 10 分钟只需消耗 1 轮,而不是每次检查都消耗一轮。后台循环会持续运行,直到容器健康或退出。
健康状态返回 200 后,发送预热请求(触发 HIP 内核编译,在 gfx942 上约需 40-45 秒):
curl -s http://localhost:<port>/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"<model_id>","messages":[{"role":"user","content":"say hi"}],"max_tokens":5}'
预热成功后,提供连接信息表,让用户可以立即调用端点:
| 字段 | 值 |
|---|---|
| 模型 | <model_id> |
| 服务模型名称 | <served-model-name or model_id> |
| 基础 URL | http://<host>:<port>/v1 |
| API 密钥 | 无(本地) |
| 端口 | <port> |
| 张量并行 | <tp> |
| 最大上下文 | <context> |
| GPU | <detected GPU> |
然后提供一个可直接运行、使用上述确切值的示例:
curl -s http://<host>:<port>/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"<model_id>","messages":[{"role":"user","content":"Hello"}]}'
远程与本地
所有脚本都接受 --host user@hostname。提供该参数时,脚本会通过 SSH 连接到目标主机。设置 ROCM_SSH_HOST 和 ROCM_SSH_USER 环境变量,即可避免每次都传入 --host。
对于远程 Docker 命令,请通过 SSH 运行:
ssh user@host 'docker run -d ...'
健康检查和预热所用的 curl URL 请使用 localhost(curl 在远程主机上运行)。
注意事项
CUDA_VISIBLE_DEVICES 被设为空字符串——ROCm 会将此变量映射到
HIP_VISIBLE_DEVICES。将其设为空字符串会隐藏所有 GPU。
CUDA_VISIBLE_DEVICES=0,1 可正常用于限制 GPU(与
HIP_VISIBLE_DEVICES=0,1 相同)。如果主机上该变量为空,请取消设置:
unset CUDA_VISIBLE_DEVICES。不要将 --env CUDA_VISIBLE_DEVICES=(空值)
传入 Docker——这也会隐藏容器内的所有 GPU。
gfx942(MI300X)上的 FP4BMM 崩溃——如果容器立即因段错误或非法指令退出:在 gfx942 上,VLLM_ROCM_USE_AITER_FP4BMM 必须设为
0。gfx942 的 gpu_overrides.json 中已正确设置此项。
请参阅 vLLM issue #34641。
HIP error: no kernel image——Docker 镜像中没有为你的 GPU 的 gfx 版本编译的内核。请使用
vllm/vllm-openai-rocm:latest;其中包含 gfx942 和 gfx950 内核。
MLA 模型需要 --block-size 1——DeepSeek-R1/V3、Kimi-K2.5。
否则 MLA 注意力后端会在不提示的情况下回退到较慢的路径。
这些模型的配方参数中已包含此项。
多 GPU 上的 MoE 模型需要 --distributed-executor-backend mp——
Qwen3-235B、GLM-4.5、MiniMax-M2。默认的分布式执行器在 ROCm 上无法可靠运行 MoE。
HIP 图捕获期间发生 OOM——如果容器日志在 "capturing CUDA graphs" 或 "capturing HIP graphs" 后显示 "out of memory",说明模型能装入
VRAM,但没有足够的余量用于图捕获。请在 vLLM 参数中添加
--enforce-eager 后重试。此选项会禁用图捕获并释放 1-2 GB 显存。代价是解码延迟略高,但模型可以运行。
"Engine core initialization failed"——这个含义不明确的错误表示引擎核心子进程已退出。请检查容器早期日志:docker logs <name> 2>&1 | head -50。常见原因包括:无权访问受限模型(未在 HF 上接受许可)、当前 vLLM 版本不支持该架构、加载权重时发生 OOM、自定义架构缺少 --trust-remote-code,或 vLLM 版本过旧,无法支持该模型(请检查配方中的 min_vllm_version)。
/dev/kfd 权限被拒绝——用户不属于 video 或 render
组。解决方法:sudo usermod -aG video,render $USER(需要重新登录)。
未配置 SSH 密钥——脚本使用 BatchMode=yes SSH。如果 SSH
失败并显示 Permission denied (publickey),请先配置基于密钥的访问。
在共享主机上限制 GPU——使用 --env HIP_VISIBLE_DEVICES=0,1
或 --env CUDA_VISIBLE_DEVICES=0,1,按索引指定目标 GPU。
HIP_VISIBLE_DEVICES 是 AMD 的标准变量;CUDA_VISIBLE_DEVICES
也可使用(ROCm 会将其映射)。不要将任一变量设为空字符串。
参考
精度兼容性、VRAM 估算、Docker 标志和已知问题: reference.md