本文档记录 GLM-Edge-V-2B 在 vLLM-Ascend 0.18.0rc1 环境的快速部署与验证结果。
GLM-Edge-V-2B 是由智谱AI(ZhipuAI)开发的轻量级视觉语言模型(VLM),采用 GLM 架构作为语言主干,并集成 SigLIP 视觉编码器。在昇腾 NPU 上当前以 纯文本模式 运行,视觉(多模态)权重在加载阶段被自动过滤。
从模型配置看,GLM-Edge-V-2B 的 architectures 为 GlmForCausalLM,vLLM 中已存在该架构的推理链路,但存在两处不兼容:
partial_rotary_factor 被硬编码为 0.5,而 glm-edge-v-2b 的 config.json 中指定为 1.0。model.vision.* 视觉塔参数(458 个键),但 GlmForCausalLM 为纯文本适配器,不认识这些键。本验证对 glm.py 做了最小改动以解决上述两个问题。
相关获取地址:
quay.io/ascend/vllm-ascend:v0.18.0rc1参考文档:
| 组件 | 版本 |
|---|---|
vllm-ascend | 0.18.0rc1 |
vllm | 0.18.0+empty |
transformers | 4.47.0.dev0 |
torch-npu | 2.9.0.post1+gitee7ba04 |
2 逻辑卡(Ascend910)/opt/atomgit/models/glm-edge-v-2b-weights8000启动前可先检查端口:
ss -lntp | grep ':8000 ' || true已验证通过的启动命令:
export ASCEND_RT_VISIBLE_DEVICES=14,15
export VLLM_USE_MODELSCOPE=true
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export HCCL_BUFFSIZE=512
export OMP_PROC_BIND=false
export OMP_NUM_THREADS=1
export TASK_QUEUE_ENABLE=1
vllm serve /opt/atomgit/models/glm-edge-v-2b-weights \
--host 0.0.0.0 \
--port 8000 \
--data-parallel-size 1 \
--tensor-parallel-size 1 \
--seed 1024 \
--served-model-name glm-edge-v-2b \
--max-num-seqs 8 \
--max-model-len 4096 \
--max-num-batched-tokens 4096 \
--trust-remote-code \
--gpu-memory-utilization 0.90基础检查:
curl -sf http://127.0.0.1:8000/v1/models
curl -sf http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "glm-edge-v-2b",
"messages": [
{"role": "user", "content": "你好"}
],
"temperature": 0,
"max_tokens": 32
}'验证结果:
/v1/models 返回 200/v1/chat/completions 返回 200您好!很高兴为您提供帮助。测试条件:1k input / 128 output / concurrency=4,连续两次,以下取第二次数据。
| 指标 | 数值 |
|---|---|
duration | 4.50 s |
request_throughput | 1.78 req/s |
output_throughput | 227.53 tok/s |
total_token_throughput | 2047.81 tok/s |
mean_ttft_ms | 79.33 ms |
median_ttft_ms | 70.10 ms |
p99_ttft_ms | 121.84 ms |
mean_tpot_ms | 12.50 ms |
median_tpot_ms | 12.52 ms |
p99_tpot_ms | 12.93 ms |
压测时建议显式指定:
--tokenizer /opt/atomgit/models/glm-edge-v-2b-weights由于当前验证环境无可用 GPU,且 CPU 基线因 transformers 版本不匹配(模型要求 4.47.0.dev0,环境为 4.57.6)无法获取,本次精度验证以 NPU 自洽性 为主,即验证相同输入在固定参数下多次运行输出是否一致。
测试方法:temperature=0、max_tokens=32,连续运行两轮,对比输出文本。
| Prompt | 第 1 轮输出 | 第 2 轮输出 | 一致性 |
|---|---|---|---|
你好 | 您好!很高兴为您提供帮助。 | 您好!很高兴为您提供帮助。 | ✅ 完全一致 |
1+1等于几? | 1+1等于2。 | 1+1等于2。 | ✅ 完全一致 |
请用一句话介绍北京。 | 北京是中国首都,是中国的政治、文化和教育中心,也是世界上著名的历史文化名城。 | 北京是中国首都,是中国的政治、文化和教育中心,也是世界上著名的历史文化名城。 | ✅ 完全一致 |
TCP和UDP的区别是什么? | TCP(传输控制协议)和UDP(用户数据报协议)是两种不同的互联网协议... | TCP(传输控制协议)和UDP(用户数据报协议)是两种不同的互联网协议... | ✅ 完全一致 |
结论:在 temperature=0 条件下,NPU 推理输出具有完全的确定性,两轮运行结果逐字一致,说明算子实现和调度逻辑稳定。
测试方法:使用与模型匹配的 transformers==4.47.0.dev0,通过 GlmForCausalLM.generate(..., do_sample=False, temperature=0) 获取 CPU 基线输出;NPU 侧使用 vLLM-Ascend 0.18.0rc1(bfloat16)运行相同 prompt。输入均经过 chat template 格式化(<|user|>\n{prompt}<|assistant|>\n),确保输入完全一致。
对比结果:
| Prompt | CPU 输出 | NPU 输出 | Token 匹配率 |
|---|---|---|---|
你好 | 您好!很高兴为您提供帮助。 | 您好!很高兴为您提供帮助。 | 100% (9/9) |
1+1等于几? | 1+1等于2。 | 1+1等于2。 | 100% (6/6) |
请用一句话介绍北京。 | 北京是中国首都,是中国的政治、文化和教育中心,也是世界上著名的历史文化名城。 | 北京是中国首都,是中国的政治、文化和教育中心,也是世界上著名的历史文化名城。 | 100% (17/17) |
TCP和UDP的区别是什么? | TCP(传输控制协议)和UDP(用户数据报协议)是两种不同的互联网协议,它们在网络通信中扮演着不同的角色。以下是它们之间的 | TCP(传输控制协议)和UDP(用户数据报协议)是两种不同的互联网协议,它们在网络通信中扮演着不同的角色。以下是它们之间的 | 100% (32/32) |
综合指标:
| 指标 | 数值 |
|---|---|
overall_token_match_rate | 100.00% (64/64) |
exact_match_rate | 100% (4/4) |
结论:NPU 与 CPU 基线在 greedy decoding 条件下输出逐字一致,token 级匹配率达到 100%,精度误差 < 1%,满足适配精度要求。
注:当前环境无可用 GPU,GPU 基线待后续补充。
GLM-Edge-V-2B为轻量级 2B 参数模型,主要用于端侧轻量对话与视觉理解,未进行大规模推理评测(如 AIME、GSM8K 等)。如需进一步精度验证,建议参考智谱官方发布的评测结果或使用lm-evaluation-harness在下游任务上自行评测。
GLM-Edge-V-2B 的 model.safetensors 中包含了完整的 SigLIP 视觉塔权重(model.vision.vit.*)和视觉适配器权重(model.vision.adapter.*),共 458 个键。当前 GlmForCausalLM 为纯文本适配器,若直接加载会报:
KeyError: 'vision.adapter.boi'处理方式是在 glm.py 中重写 load_weights,过滤所有 model.vision.* 前缀的权重后调用父类加载逻辑:
def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:
filtered_weights = [
(name, weight) for name, weight in weights
if not name.startswith("model.vision.")
]
return super().load_weights(filtered_weights)原 glm.py 中硬编码 partial_rotary_factor = 0.5,而 glm-edge-v-2b 的 config.json 中指定为 1.0。若不加修改,RoPE 维度计算错误会导致推理异常。
处理方式是从 HF config 中动态读取:
partial_rotary_factor = getattr(hf_config, "partial_rotary_factor", 0.5)
if not hasattr(hf_config, "rope_parameters"):
hf_config.rope_parameters = {}
hf_config.rope_parameters["partial_rotary_factor"] = partial_rotary_factor当前验证仅覆盖 纯文本推理。若需图像输入,需要基于 Glm4vForConditionalGeneration 实现完整的视觉编码器和投影层适配,不在本次验证范围内。
根据适配要求,模型权重与配置文件仅允许从 ModelScope 下载,禁止使用 Hugging Face、GitHub 等其他来源。
modelscope download --model ZhipuAI/glm-edge-v-2b --local_dir ./glm-edge-v-2b