
1. 为什么我盯上了 AMD 云实例跑 Gemma4 这件事第一次看到“15 分钟部署 Gemma4”这个说法我的反应是要么是标题党要么是有人把模型量化到只剩骨架。Gemma4 这个量级的模型光是权重加载就得吃掉不少显存再加上推理框架的初始化开销15 分钟能跑起来已经算快的。但真正让我感兴趣的是标题里那个“AMD ROCm 云实例”——这才是整件事的核心变量。大多数人一提大模型推理脑子里第一反应就是 NVIDIA 的卡加 CUDA 生态这几乎成了肌肉记忆。但现实是AMD 的 Instinct 系列加速卡在显存容量和单位算力成本上这两年确实有竞争力尤其是 MI 系列。问题在于ROCm 这套软件栈的成熟度和 CUDA 之间还有差距很多人在 AMD 卡上跑推理第一步就卡在环境配置上根本走不到模型加载那一步。所以“15 分钟部署”这个数字如果真能实现那它背后一定有一套被验证过的、可复现的流程而不是靠运气。我这次做的事情就是把一个 AMD ROCm 云实例从零开始挖一遍从实例选型、驱动确认、ROCm 环境验证到 vLLM 的安装、Gemma4 的加载、推理服务的暴露再到实际压测和踩坑记录。整个过程我会把每一步的“为什么”讲清楚因为 AMD 这套东西和 CUDA 的思维习惯差别不小照搬 NVIDIA 的经验很容易翻车。这篇文章适合几类人手里有 AMD 云实例但不知道怎么用起来的、想对比 AMD 和 NVIDIA 推理成本的、以及单纯想搞清楚 vLLM 在 ROCm 上到底能不能稳定跑的。如果你只是想看个结论那我先给能跑但有几个关键点不注意15 分钟会变成 3 小时。2. 实例选型和环境确认别急着装驱动2.1 选卡之前先搞清楚 ROCm 的版本支持矩阵AMD 的加速卡型号不少但 ROCm 对每款卡的支持程度是不一样的。MI250、MI300X 这些是官方重点支持的MI100 系列相对老一些而消费级的 Radeon 卡虽然也能跑 ROCm但坑会多很多。云实例上常见的是 MI250X 和 MI300X这两个在 ROCm 6.x 上的支持都比较完整。我这次用的是 MI300X 的实例显存 192GB这个容量跑 Gemma4 的 FP16 权重绰绰有余甚至可以做多并发。选它的理由很直接显存大意味着你可以少做量化少做量化意味着推理质量损失小而 Gemma4 这种模型一旦量化到 4bit输出质量下降是能感知到的。提示选实例的时候一定要确认云厂商给的 ROCm 版本。有些实例预装了 ROCm 5.x而 vLLM 的新版本对 ROCm 6.x 的依赖比较强版本不匹配会导致编译失败。2.2 登录实例后第一件事不是装东西是确认卡被认出来了很多人拿到实例就急着pip install结果装完发现 vLLM 根本检测不到 GPU。正确的顺序是先确认系统层面能识别到 AMD 加速卡。# 确认 PCI 设备层面能看到 AMD 的加速卡 lspci | grep -i amd # 确认 ROCm 驱动和运行时是否正常 rocm-smi # 查看 ROCm 版本 cat /opt/rocm/.info/versionrocm-smi这个命令很关键它会列出所有被 ROCm 识别到的加速卡、显存占用、温度、功耗等信息。如果这个命令报错或者输出为空那后面所有事情都不用做了先解决驱动问题。我遇到过一种情况lspci能看到 AMD 的设备但rocm-smi没反应。这通常是因为内核模块没加载或者实例的镜像里 ROCm 运行时没装全。这时候需要检查dmesg里有没有 amdgpu 相关的报错以及/dev/kfd和/dev/dri这两个设备节点是否存在。# 检查关键设备节点 ls -l /dev/kfd ls -l /dev/dri/ # 查看内核日志里 amdgpu 的加载情况 dmesg | grep -i amdgpu | tail -20/dev/kfd是 ROCm 的内核融合驱动节点vLLM 和 PyTorch 都依赖它。如果这个节点不存在说明 amdgpu 内核模块没正确加载需要重新安装或配置驱动。2.3 用户权限这个坑第一次用 AMD 云实例的人基本都会踩ROCm 默认要求用户属于render和video组否则没有权限访问/dev/kfd和/dev/dri。云实例上如果你用的是非 root 用户很可能一上来就遇到权限拒绝。# 把当前用户加入必要的组 sudo usermod -aG render,video $USER # 重新登录使组权限生效或者用 newgrp 临时切换 newgrp render这个坑的隐蔽之处在于rocm-smi可能用 sudo 能跑但普通用户跑不了而 vLLM 是以普通用户身份运行的结果就是模型加载时报一个很模糊的错误你根本想不到是权限问题。我的建议是环境确认阶段就用普通用户身份跑一遍rocm-smi确保权限没问题再往下走。3. vLLM 在 ROCm 上的安装源码编译还是预编译包3.1 为什么 vLLM 在 AMD 上的安装比 NVIDIA 麻烦NVIDIA 平台上vLLM 的安装基本就是pip install vllm因为 CUDA 的预编译 wheel 很成熟。但 ROCm 平台上vLLM 的官方 wheel 覆盖的 ROCm 版本和 Python 版本组合有限很多时候你需要从源码编译或者用 AMD 官方提供的 Docker 镜像。这里有个决策点是用 Docker 镜像还是裸机安装。Docker 镜像的好处是环境隔离、依赖固定AMD 官方也维护了 ROCm 的 PyTorch 镜像vLLM 可以基于它来装。裸机安装的好处是启动快、调试方便但依赖冲突的风险高。我这次选的是裸机安装加虚拟环境原因是云实例的磁盘 IO 在 Docker 层会有额外开销而且我想把整个流程拆开看清楚每一步在做什么。3.2 创建虚拟环境并锁定 PyTorch 的 ROCm 版本PyTorch 的 ROCm 版本和 CUDA 版本是两条独立的发布线装错了就是 CPU 版本推理速度会慢到让你怀疑人生。# 创建虚拟环境 python3 -m venv vllm-env source vllm-env/bin/activate # 安装 ROCm 版本的 PyTorch注意 index-url 指向 ROCm 的源 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.2装完之后一定要验证 PyTorch 能不能看到 GPUimport torch print(torch.cuda.is_available()) # ROCm 下这个接口名还是 cuda别被名字骗了 print(torch.cuda.device_count()) print(torch.cuda.get_device_name(0))注意ROCm 版的 PyTorch 里torch.cuda这个命名空间是保留的它实际调用的是 ROCm 后端。这是历史遗留的命名问题不是装错了。如果torch.cuda.is_available()返回 False先别急着装 vLLM回去检查 ROCm 驱动和 PyTorch 版本的匹配关系。这一步不通后面全是白费。3.3 安装 vLLM 的两种路径和各自的代价路径一直接 pip 安装预编译包。pip install vllm这个方式最快但前提是你的 ROCm 版本和 Python 版本正好有对应的 wheel。如果没有pip 会尝试从源码编译而源码编译 vLLM 在 ROCm 上会触发大量 C 和 HIP 代码的编译时间可能超过 30 分钟而且中间任何依赖缺失都会导致失败。路径二从源码安装指定 ROCm 架构。git clone https://github.com/vllm-project/vllm.git cd vllm export PYTORCH_ROCM_ARCHgfx942 # MI300X 的架构代号 pip install -e .PYTORCH_ROCM_ARCH这个环境变量很关键它告诉编译器针对哪个 GPU 架构生成代码。MI300X 是gfx942MI250 是gfx90a。如果不设置编译出来的 kernel 可能不兼容你的卡运行时报 illegal instruction 之类的错误。我实测下来源码编译在 MI300X 上大概需要 20 到 25 分钟主要时间花在 attention kernel 和量化 kernel 的编译上。如果你赶时间优先找预编译包如果要长期用源码编译一次然后缓存 wheel 更划算。4. Gemma4 加载与推理服务启动的完整链路4.1 模型权重的获取和存放位置Gemma4 的权重文件不小FP16 精度下大概几十 GB。云实例的系统盘通常不大建议挂载数据盘或者确认系统盘有足够空间。# 查看磁盘空间 df -h # 建议把模型放在数据盘比如 /data/models mkdir -p /data/models/gemma4权重下载的方式取决于你从哪里获取。如果是内部镜像或者对象存储用对应的 CLI 工具拉取。下载完之后确认文件完整性尤其是config.json、tokenizer.json和权重分片文件是否齐全。4.2 启动 vLLM 服务时的关键参数vLLM 的启动命令看起来简单但几个参数直接决定了能不能跑起来、跑得好不好。python -m vllm.entrypoints.openai.api_server \ --model /data/models/gemma4 \ --tensor-parallel-size 1 \ --dtype float16 \ --max-model-len 8192 \ --gpu-memory-utilization 0.9 \ --port 8000逐个解释这些参数为什么这么设--tensor-parallel-size 1单卡推理就设 1。如果你有多张卡可以设成卡数来做张量并行但 Gemma4 在 MI300X 的 192GB 显存下单卡足够没必要引入并行带来的通信开销。--dtype float16MI300X 对 FP16 的支持很好用 FP16 比 BF16 在部分 kernel 上更快。如果你的模型权重是 BF16 的这里要对应改成bfloat16否则会报类型不匹配。--max-model-len 8192这个值决定了 KV Cache 的预分配大小。设得越大显存占用越高。Gemma4 支持更长的上下文但如果你实际用不到那么长设小一点能省显存给并发用。--gpu-memory-utilization 0.9vLLM 会按这个比例预分配显存。设 0.9 意味着留 10% 给系统和其他开销。如果设成 0.95 以上有时候会因为显存碎片导致启动失败。提示第一次启动时建议加上--enforce-eager它会禁用 CUDA Graph 捕获虽然推理速度会慢一些但能避免很多图捕获阶段的兼容性问题。等确认能跑通之后再去掉这个参数做性能优化。4.3 启动过程中的日志该怎么读vLLM 启动时会打印大量日志几个关键节点需要关注Loading model weights出现后如果卡住超过几分钟通常是磁盘 IO 慢或者权重文件有问题。Capturing CUDA graphs在 ROCm 上对应的是 HIP graph这一步如果报错先用--enforce-eager绕过。Starting OpenAI API server出现后服务才算真正就绪。我遇到过启动时卡在Loading model weights很久的情况排查下来是模型放在网络存储上读取带宽不够。把权重挪到本地 NVMe 盘之后加载时间从几分钟降到几十秒。5. 实测性能与那些文档里不会写的坑5.1 推理延迟和吞吐的实测数据在 MI300X 单卡上Gemma4 FP16 精度输入 512 token、输出 256 token 的场景下首 token 延迟大概在 200 到 400 毫秒之间后续 token 的生成速度在每秒 40 到 60 token 左右。这个数据会随着并发数上升而下降因为显存带宽是共享的。我用 vLLM 自带的 benchmark 脚本做了简单压测python benchmarks/benchmark_serving.py \ --backend vllm \ --model /data/models/gemma4 \ --dataset-name sharegpt \ --num-prompts 100 \ --request-rate 5并发设为 5 的时候吞吐大概能到每秒 150 token 左右再往上加并发延迟上升比较明显。这说明单卡 MI300X 跑 Gemma4适合中等并发场景如果要支撑高并发要么加卡做张量并行要么上量化。5.2 ROCm 上特有的坑显存碎片和 HIP graph 捕获失败CUDA 上很少遇到的显存碎片问题在 ROCm 上出现的概率高不少。表现是明明rocm-smi显示显存够但 vLLM 启动时报 OOM。原因通常是之前的进程没有完全释放显存或者 ROCm 的显存分配器碎片化。解决办法有两个一是重启实例简单粗暴但有效二是在启动前手动清理残留进程。# 查看占用 GPU 的进程 rocm-smi --showpids # 如果有残留进程kill 掉 kill -9 pidHIP graph 捕获失败是另一个高频问题。日志里会出现graph capture failed或者hipErrorStreamCaptureUnsupported之类的错误。这个问题的根源是某些算子不支持图捕获或者 ROCm 版本和 vLLM 版本的兼容性问题。最直接的绕过方式就是--enforce-eager代价是损失一部分推理性能。5.3 模型输出质量的验证不能省部署完之后一定要做一轮输出质量验证不能只看服务能不能响应。因为量化或者精度转换的问题可能导致模型输出变得很奇怪但服务本身不报错。curl http://localhost:8000/v1/completions \ -H Content-Type: application/json \ -d { model: /data/models/gemma4, prompt: 用三句话解释什么是张量并行, max_tokens: 200, temperature: 0.7 }检查返回的内容是否连贯、是否符合预期。如果输出是乱码或者重复片段可能是 tokenizer 配置有问题或者模型权重加载不完整。6. 关于成本、扩展性和后续优化的一些个人判断6.1 AMD 云实例跑推理的成本账怎么算单纯看单位算力价格AMD 的实例在某些云厂商那里确实比同级别的 NVIDIA 实例便宜。但成本不能只看卡的价格还要算上调试时间、生态兼容性带来的隐性成本。我的判断是如果你做的是标准化的推理服务模型和框架都比较主流AMD 实例的性价比是成立的。但如果你需要用到很多冷门的算子或者自定义 kernelROCm 的生态支持会让你多花不少时间。这个时间成本在小规模实验阶段不明显但在生产环境里是要算进总账的。6.2 多卡扩展时需要注意的通信问题MI300X 之间通过 Infinity Fabric 互联带宽很高但 vLLM 的张量并行在 ROCm 上的通信实现和 CUDA 的 NCCL 不完全一样。多卡启动时要确认 RCCLROCm 的通信库版本和 vLLM 兼容。# 多卡启动示例 python -m vllm.entrypoints.openai.api_server \ --model /data/models/gemma4 \ --tensor-parallel-size 2 \ --dtype float16 \ --port 8000多卡场景下如果 RCCL 初始化失败日志里会有rccl相关的错误。这时候检查LD_LIBRARY_PATH是否包含 ROCm 的库路径以及各卡之间的拓扑是否被正确识别。6.3 后续可以尝试的优化方向一个方向是量化。vLLM 支持 AWQ 和 GPTQ 量化在 ROCm 上部分量化 kernel 已经可用。量化到 4bit 能把显存占用降到四分之一左右吞吐提升明显但输出质量会有损失需要根据业务场景权衡。另一个方向是调整 KV Cache 的管理策略。vLLM 的 PagedAttention 在 ROCm 上的表现和 CUDA 上有差异可以通过调整--block-size参数来优化显存利用率和吞吐。这个参数需要实测调优没有万能值。我在实际使用中的体会是AMD ROCm 这套栈跑大模型推理现在已经过了“完全不能用”的阶段进入了“能用但需要调”的阶段。15 分钟部署 Gemma4 这个目标在环境预装好的前提下是可达的但前提是你对 ROCm 的脾气有基本了解。第一次上手的话留出两到三个小时的调试时间比较现实。踩过几次坑之后后面再部署就快了因为你知道该看哪些日志、该检查哪些节点。