1. 8×A800 跑 GLM-5.2-NVFP4,TP8 推理链路到底卡在哪
GLM-5.2-NVFP4 是一套面向 NVFP4 量化权重的大模型推理方案,简单说就是把原本需要更大显存才能装下的权重压到 4bit 浮点格式,让单机多卡也能跑起来。它适合谁?适合手上有 8 卡 A800、想在内网自建推理服务、又不想被单卡显存卡死的团队。A800 是 80GB 显存、PCIe 互联的卡,8 张凑一起理论上有 640GB 显存池,但真正落地时你会发现,权重切分、注意力后端、KV Cache 精度、投机解码这几件事只要有一件没配对,服务要么起不来,要么一起来就崩。
上篇我们聊了为什么要打补丁、怎么修 API 漂移。这篇直接进入 TP8 推理链路的落地:vLLM 启动参数怎么配、显存和吞吐怎么观测、请求侧怎么用统一 Key 接入。TP8 指的是 tensor-parallel-size=8,也就是把模型权重按张量维度切成 8 份,每张卡放一份,前向计算时通过 all-reduce 同步。GLM-5.2-NVFP4 的权重约 433GB,TP8 之后每卡约 54GB,加上 KV Cache 和 CUDA graph,单卡占用会到 70GB 上下,所以 TP4 是绝对放不下的,必须 TP8。
我试过在 A800 上直接套官方 Blackwell 的启动命令,结果 prefill 阶段直接抛NotImplementedError at forward_mha,原因是 v0.26.0 的 base 实现里 MHA 路径没写完,而 A800 又不支持官方默认的稀疏后端,必须强制走 TRITON_MLA_SPARSE 并打开sparse_mla_force_mqa。这一篇会把这条链路完整串起来,包括启动配置、健康检查、压测验证,以及请求侧通过 TaoToken 统一 Key 完成调用对接和结果核验。
2. TaoToken 前置准备:统一 Key 与 API 通道怎么接
在讲请求侧接入之前,先把 TaoToken 这一侧的准备说清楚。TaoToken 提供的是统一 Key 和 API 通道,你可以把它理解成一个「请求入口层」:不管你后端跑的是 vLLM、还是别的推理框架,调用方只需要拿一个 Key、对准一个 Base URL,就能把请求发出去。这样做的好处是,当你的后端从 A800 换到别的机器、或者模型名从 glm-5.2-nvfp4 换成别的,调用方代码不用大改,只改配置就行。
你需要先拿到两样东西:API Key 和 Base URL。API Key 在控制台的 API Keys 页面创建,Base URL 用https://taotoken.net/api。注意这里不要加任何多余路径,vLLM 的 OpenAI 兼容接口本身会带/v1,所以最终请求地址是https://taotoken.net/api/v1/chat/completions。如果你用的是 Claude Code 这类工具,Base URL 填https://taotoken.net/api,Key 填你创建的那串,Model ID 填你后端--served-model-name指定的名字,比如glm-5.2-nvfp4。
这里有个容易踩的坑:很多人会把 Base URL 写成https://taotoken.net/api/v1,然后在代码里又拼一次/v1,结果变成/api/v1/v1/chat/completions,直接 404。记住一个原则:Base URL 只到/api,/v1由 SDK 或你的请求代码自己补。另外,Key 的权限要确认一下,如果你只是做推理调用,用默认的调用权限就行,不需要开管理权限。
创建 Key 的入口在控制台的 API Keys 页面,模型对话入口可以用来做快速验证,Coding Plan 适合长期编码和 Agent 场景。如果你后面要跑批量压测,建议单独建一个 Key,方便按 Key 维度看用量和限流。前置准备做完之后,后端 vLLM 服务和前端调用侧就通过这个统一 Key 串起来了,接下来进入可复制的配置环节。
3. 可复制配置:vLLM 启动参数与请求侧 settings 片段
这一节给的是可以直接复制粘贴的配置。先看 vLLM 启动。假设模型权重放在/data/models/GLM-5.2-NVFP4,镜像用打过补丁的vllm/vllm-openai:v0.26.0-glm52-sm80,启动命令如下:
docker run -d --name glm52-nvfp4 \ --gpus all \ --shm-size=32g \ -e VLLM_ATTENTION_BACKEND=TRITON_MLA_SPARSE \ -e PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \ -v /data/models:/models \ -p 8001:8001 \ vllm/vllm-openai:v0.26.0-glm52-sm80 \ /models/GLM-5.2-NVFP4 \ --host 0.0.0.0 --port 8001 \ --tensor-parallel-size 8 \ --trust-remote-code \ --dtype bfloat16 \ --gpu-memory-utilization 0.95 \ --max-model-len 65536 \ --kv-cache-dtype bfloat16 \ --max-num-seqs 16 \ --max-num-batched-tokens 8192 \ --served-model-name glm-5.2-nvfp4 \ --attention-config '{"sparse_mla_force_mqa": true}' \ --tool-call-parser glm47 --enable-auto-tool-choice \ --reasoning-parser glm45 \ --speculative-config '{"method":"mtp","num_speculative_tokens":5}'几个参数必须重点说。--tensor-parallel-size 8是硬性要求,TP4 会超显存。VLLM_ATTENTION_BACKEND=TRITON_MLA_SPARSE是 A800 上唯一可用的稀疏后端,不设这个会回退到 dense,性能掉一大截。--kv-cache-dtype bfloat16注意合法值是bfloat16,不是bf16,写bf16会直接报invalid choice。--attention-config '{"sparse_mla_force_mqa": true}'必填,不加的话真实 prefill 请求必崩。--reasoning-parser glm45把思考过程隔离到 reasoning 字段,content 只留答案。--speculative-config开 MTP 投机解码,sm80 实测可用。
请求侧如果用 Python SDK,配置片段如下:
from openai import OpenAI client = OpenAI( base_url="https://taotoken.net/api", api_key="你的_TAOTOKEN_KEY", ) resp = client.chat.completions.create( model="glm-5.2-nvfp4", messages=[{"role": "user", "content": "What is 17 multiplied by 24?"}], max_tokens=150, temperature=0.6, ) print(resp.choices[0].message.content)如果你用 Claude Code 或 Cline 这类工具,配置写成 JSON 或 TOML 都行。以 settings 片段为例:
{ "baseUrl": "https://taotoken.net/api", "apiKey": "你的_TAOTOKEN_KEY", "model": "glm-5.2-nvfp4" }这三件套 Base URL、Key、Model ID 必须齐全,缺一个都会报错。Model ID 要和你--served-model-name完全一致,大小写敏感。配置写完之后,先别急着压测,先做健康检查。
4. 验证请求与成功结果:日志、冒烟、压测三步走
服务起来之后,第一步看日志。执行docker logs -f glm52-nvfp4,等到出现这两行,说明走的是稀疏路径而不是 dense 回退:
[sparse_attn_indexer.py:790] DeepGEMM not supported on this platform; using Triton fallback for sparse attention indexer. [cuda.py:487] Using TRITON_MLA_SPARSE attention backend out of potential backends: ['TRITON_MLA_SPARSE'].再等到Application startup complete.,服务就算就绪了。这一步很关键,如果日志里出现的是 dense 后端,说明VLLM_ATTENTION_BACKEND没生效,后面压测数据会很难看。
第二步 HTTP 冒烟。先看模型列表:
curl -s http://127.0.0.1:8001/v1/models再发一个真实请求:
time curl -s http://127.0.0.1:8001/v1/chat/completions \ -H 'Content-Type: application/json' -d '{ "model": "glm-5.2-nvfp4", "messages": [{"role":"user","content":"What is 17 multiplied by 24? Answer briefly."}], "max_tokens": 150, "temperature": 0.6 }'实测返回 content 是 408,reasoning 字段里包含完整思考过程。如果你看到 content 为空、reasoning 里塞满内容,说明--reasoning-parser glm45生效了,这是预期行为。
第三步压测。仓库里一般会有几个脚本,比如bench.py做并发压测、ttft_test.py测首 token 延迟、ctx_4x32k_test.py测 4 并发 × 32k 上下文。跑压测时重点看三个指标:吞吐(tok/s)、TTFT(首 token 延迟)、GPU 利用率。8 卡 A800 在 TP8 + MTP 下,单流吞吐能到 74–85 tok/s,4 并发 160–196 tok/s,16 并发峰值 386–393 tok/s。GPU 利用率 94–96%,显存每卡约 57GB 权重 + 13.2GB KV + 2.4GB CUDA graph。TTFT 在 prompt 80–960 token 时是 0.2–0.5s。这些数据可以作为你验收的基线。
请求侧通过 TaoToken 统一 Key 调用时,把上面 curl 里的http://127.0.0.1:8001换成https://taotoken.net/api,加上Authorization: Bearer 你的_KEY,其余 body 不变。如果返回 200 且 content 正常,说明整条链路通了。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
这一节把真实会遇到的报错列出来,对照着改。
401 Unauthorized最常见。原因通常是 Key 没带、Key 写错、或者 Base URL 拼错导致请求打到了别的路径。检查三件事:请求头里有没有Authorization: Bearer <key>,Base URL 是不是只到/api,Key 有没有多余空格。如果你用的是 Claude Code,检查 settings 里的 apiKey 字段是不是被引号包错了。
local proxy failed一般出现在工具侧配置了本地代理但代理没起来,或者 Base URL 指向了本地端口但服务没监听。先确认 vLLM 容器-p 8001:8001映射正常,curl http://127.0.0.1:8001/v1/models能通。如果通,再把工具里的 Base URL 改成https://taotoken.net/api,不要走本地代理。
reading choices这类报错通常是响应体结构不对,比如后端返回了错误 JSON,但调用方直接去读choices[0]。先打印完整响应体,看是不是{"error": ...}。常见原因是 Model ID 写错,后端找不到对应模型,返回 404 或 400。确认 Model ID 和--served-model-name一致。
OAuth相关报错多出现在 Claude Code 或类似工具里,工具默认走 OAuth 登录流程,但你用的是 API Key 模式。需要在配置里显式指定 API Key 模式,把 Base URL 和 Key 填对,不要触发登录流程。如果工具同时支持两种模式,优先选 API Key。
还有一个隐蔽的坑:--kv-cache-dtype bf16会报invalid choice: 'bf16',合法值是bfloat16。AttributeError: 'XPUMLASparseMetadata' object has no attribute 'num_decode_tokens'是 v0.26.0 元数据类缺字段,需要补字段。TypeError: non-default argument follows default argument是 dataclass 默认字段位置不对,把默认字段放最后。每次改代码重建镜像只要几秒,但重启要重新加载 433G 权重,页缓存热时约 6 分钟,冷读约 22 分钟,尽量一次多修几处再重启。
6. 语义一致 CTA:把统一 Key 接入落到你的实际链路
整条链路走下来,后端是 8×A800 上的 vLLM TP8 推理,前端是 TaoToken 统一 Key 接入。你可能会问,为什么不直接调本地 8001 端口?因为本地端口只适合单机调试,一旦你要做多环境切换、多调用方共用、或者按 Key 看用量,统一入口就省事很多。调用方只认一个 Base URL 和一个 Key,后端换机器、换模型名,调用方配置不用动。
如果你现在卡在排障阶段,比如 401 或者 local proxy failed,建议先去 API Keys 页面确认 Key 状态,再对照接入文档检查 Base URL 和请求头。如果你已经通了,想验证模型输出质量,可以用模型对话入口做快速对比。如果你是要长期跑编码或 Agent 任务,Coding Plan 更适合,因为它按长期用量做了优化。
回到这篇的主题,GLM-5.2-NVFP4 在 8×A800 上跑 TP8,核心就三件事:启动参数配对(TP8 + TRITON_MLA_SPARSE + bfloat16 KV + sparse_mla_force_mqa)、验证动作到位(日志看后端、冒烟看返回、压测看吞吐)、请求侧统一 Key 接入(Base URL 到 /api、Key 带对、Model ID 一致)。这三件事做完,链路就稳了。剩下的就是根据你的实际并发和上下文长度,调--max-num-seqs和--max-model-len,在吞吐和显存之间找平衡。