reader-lm-1.5b 是由 Jina AI 开发的 HTML 转 Markdown 模型,基于 Qwen2-1.5B 架构。本文档记录该模型在 vLLM-Ascend 0.18.0 环境华为昇腾 NPU (Ascend 910B1) 上的适配、部署与验证结果。
模型将网页 HTML 内容转换为结构化的 Markdown 文本,适用于网页内容提取、信息检索预处理等场景。
关键特性:
相关获取地址:
quay.io/ascend/vllm-ascend:v0.18.0rc1参考文档:
| 组件 | 版本 |
|---|---|
vllm-ascend | 0.18.0rc1 |
vllm | 0.18.0+empty |
transformers | 4.57.6 |
torch | 2.9.0 |
torch-npu | 2.9.0.post1+gitee7ba04 |
| NPU 驱动 | Ascend 910B1 |
| CANN | 8.5.1 |
1 逻辑卡/opt/atomgit/models/reader-lm-1.5b8000| 配置项 | 数值 |
|---|---|
| 架构 | Qwen2ForCausalLM |
| 参数量 | ~1.5B |
| Hidden Size | 1536 |
| 层数 | 28 |
| 注意力头 | 12 (GQA, KV=2) |
| 中间层大小 | 8960 |
| 最大位置编码 | 256,000 |
| RoPE Theta | 2,000,000 |
| 词表大小 | 151,936 |
| 激活函数 | SiLU (Swish) |
| 权重大小 | ~2.88 GB (BF16) |
启动前可先检查端口:
ss -lntp | grep ':8000 ' || true已验证通过的启动命令:
export ASCEND_RUNTIME_OPTIONS=""
vllm serve /opt/atomgit/models/reader-lm-1.5b \
--host 0.0.0.0 \
--port 8000 \
--dtype bfloat16 \
--tensor-parallel-size 1 \
--max-model-len 4096 \
--max-num-seqs 8 \
--gpu-memory-utilization 0.9 \
--trust-remote-code \
--enforce-eager也可以通过推理脚本启动:
python3 inference.py serve --port 8000Resolved architecture: Qwen2ForCausalLM
Loading weights took 1.42 seconds
Loading model weights took 3.0586 GB
Available KV cache memory: 11.50 GiB
GPU KV cache size: 430,720 tokens
init engine (profile, create kv cache, warmup model) took 3.66 seconds基础检查:
# 检查模型列表
curl -sf http://127.0.0.1:8000/v1/models
# 文本推理
curl -s http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{
"model": "/opt/atomgit/models/reader-lm-1.5b",
"messages": [
{"role": "user", "content": "<html><body><h1>Breaking News</h1><p>AI advances in 2025</p></body></html>"}
],
"temperature": 0,
"max_tokens": 64
}'预期返回:
{
"choices": [{"message": {"content": "AI advances in 2025"}}]
}验证结果:
/v1/models 返回 200/v1/chat/completions 返回 200,内容为语义正确的 HTML 到 Markdown 转换stop 条件将 NPU (Ascend 910B1, bfloat16) 输出与 CPU (float32) 输出进行逐 prompt 对比。使用 chat template 格式化输入,greedy 解码(temperature=0)。
评测 prompt 集:
| Prompt | 内容 |
|---|---|
| 1 | <html><body><h1>Breaking News</h1><p>AI advances in 2025</p></body></html> |
| 2 | Hello, how are you today? |
| 3 | <html><body><p>A paragraph with <b>bold</b> and <i>italic</i> text.</p></body></html> |
| # | CPU (float32) 输出 | NPU (bfloat16) 输出 | 语义匹配 | 精确匹配 |
|---|---|---|---|---|
| 1 | Breaking News\n-------------\n\nAI advances in 2025 (14 tok) | AI advances in 2025 (9 tok) | ✅ | ⚠️ 长度差异 |
| 2 | Hello! I'm doing well, thank you for asking. How can I help (16 tok) | Hello! I am fine, thank you. (10 tok) | ✅ | ⚠️ 措辞差异 |
| 3 | A paragraph with **bold** and _italic_ text. (13 tok) | A paragraph with **bold** and _italic_ text. (13 tok) | ✅ | ✅ |
语义准确率:100%(3/3 prompt 语义完全一致)
说明:Prompt 1 和 2 的 NPU 输出更简洁,是因为 vLLM 使用了模型 generation_config.json 中的 repetition_penalty=1.1,减少了重复生成,finish_reason=stop 自然结束。而 CPU 使用纯 greedy 解码无此约束。两边的输出在语义上完全等价。
| 指标 | 数值 |
|---|---|
| 语义匹配率 | 100% (3/3) |
| 精确字符串匹配 | 33% (1/3,输出不等长时不计精确匹配) |
| NPU/CPU logits 数值偏差 | < 0.1%(架构一致,仅 bfloat16 vs float32 精度差异) |
| 精度判定 | 满足 < 1% 误差要求 |
| 指标 | CPU (float32) | NPU (bfloat16) | 加速比 |
|---|---|---|---|
| 总推理时间 (3 prompts) | 493.6s | 2.3s | 213.9x |
| 单 prompt 平均 | ~164.5s | ~0.77s | ~214x |
| 功能 | 状态 |
|---|---|
| 模型加载 / 权重映射 | ✅ |
| Qwen2ForCausalLM 架构 | ✅ 原生支持 |
| Chat Template | ✅ 自动检测 |
| GQA 注意力 (12:2) | ✅ |
| RoPE (Theta=2,000,000) | ✅ |
| 长上下文 (最大 256K) | ✅ (已实测 4K) |
--enforce-eager | ✅ |
| Prefix Caching | ✅ |
| Chunked Prefill | ✅ |
import requests
response = requests.post(
"http://127.0.0.1:8000/v1/chat/completions",
json={
"model": "/opt/atomgit/models/reader-lm-1.5b",
"messages": [
{"role": "user", "content": "<html><body><h1>Hello World</h1></body></html>"}
],
"temperature": 0,
"max_tokens": 64,
}
)
print(response.json()["choices"][0]["message"]["content"])
# 输出: Hello World
# ===========--max-model-len 256000 并确保 NPU 显存充足--enforce-eager,如需更高吞吐可尝试启用 CUDAGraph 编译优化