atlasleong/vn-address-normalizer-npu
模型介绍
文件和版本
Pull Requests
讨论
分析

qox/vn-address-normalizer(越南地址标准化)昇腾 NPU 推理适配

任务: text-normalization(文本标准化 —— 越南地址 → 2025 年行政区划规范形式) 目标设备: npu:6(Ascend 910B4-1,直连物理卡,无 ASCEND_RT_VISIBLE_DEVICES 映射) 推理引擎: torch_npu · 模型: qox/vn-address-normalizer · HF 源修订: 5d0de6d07356774e861f72684e4807bdbc137351

本目录是一个自包含的越南地址标准化昇腾 NPU 推理交付物。它从本地检查点 model.safetensors 加载真实完整权重(6,589,197 参数,严格加载,无缺失/多余键), 在物理 npu:6 上以确定性 eval 前向推理,对越南语地址文本输出规范化的行政区划 地址,同时写入 logs/npu_inference.log、logs/npu_device_call.log 与 logs/npu_result.json。

图片说明
agent_workflow本次 ModelAgent 适配工作流(真实命令)
modelagent_live_sessionModelAgent 实况会话(真实脱敏 transcript)
npu_device_callnpu:6 设备调用与进程证据(真实日志渲染)
model_result最终 NPU 推理结果(真实日志渲染)

模型简介

qox/vn-address-normalizer 是一个越南语地址标准化模型:给定一段非规范(常含缩写、 无音调、顺序混杂)的越南地址文本,模型输出 2025 年行政区划重组后的规范地址 (标准「坊/社/郡 → 省/直辖市」形式)。

  • 推理目标:text-normalization —— 将原始地址字符串标准化为官方行政区划名。
  • 本交付使用真实完整权重 model.safetensors(6,589,197 参数), 不使用 ONNX、随机权重或配置占位。
  • 本轮修复(round 2):结果 JSON 顶层补充非空 output(由标准化地址结果构成), 并固定直连物理 npu:6;--device npu:6(或 NPU_DEVICE=npu:6)保证模型、输入、 输出全部在 npu:6;不使用 ASCEND_RT_VISIBLE_DEVICES 映射;不允许 CPU 推理/回退。

模型架构(与上游模型卡 / config.json / 权重键完全一致)

超参数值
architectureSeq2Seq Transformer(字符级编码-解码)
MAX_SRC / MAX_TGT128 / 96
D_MODEL / N_HEADS256 / 4
ENC_LAYERS / DEC_LAYERS4 / 3
D_FF1024
SRC_VOCAB / TGT_VOCAB287 / 269(含 <PAD> <UNK> <BOS> <EOS>)
COVERAGE_PCT79.3
参数量6,589,197(float32)

推理流程:省份检测(正则 + 别名表)→ 坊/社提示检测 → 受限 trie 构建 → 省份约束 beam search(beam=5,最大 96 步)→ 结果保证存在于规范地址库。

关于词典文件:src_vocab.json / tgt_vocab.json 不在固定修订的仓库树中 (上游提交历史中曾上传后被删除)。本交付从上游 git 历史中恢复真实词典 blob (git fsck --unreachable + git cat-file blob),并核对词表大小 287/269、特殊符号 位于 0..3、唯一性与语料覆盖——非重建、非伪造。

版本与哈希(已核对)

文件SHA256字节数
model.safetensors(本交付使用的真实全量模型)4fcaae4f7a2e725aad234533e579884daa227c761b82c1c6a82c7ff73bbc2e3a26,368,100
model_v3_final/src_vocab.json(恢复自上游 git 历史)08146418c562917aa16a77db95df89f7690dafa45853a0c069286333cc4c07e81,797
model_v3_final/tgt_vocab.json(恢复自上游 git 历史)7acc5111b3205d0607cb4608aa3c149d54f4aae836affc4e323e6e0cb42182901,675
  • 模型源:https://huggingface.co/qox/vn-address-normalizer @ revision 5d0de6d07356774e861f72684e4807bdbc137351
  • 权重许可:MIT;权重在本地 /work/pipeline/models/other40/vn-address-normalizer/, 运行时绝不联网下载。

环境依赖清单

运行环境(实测)

组件版本
OS / 架构Linux aarch64
NPUAscend 910B4-1(npu-smi 25.5.1,8 卡,本任务固定使用物理 npu:6)
CANN8.5.1(driver 25.5.1)
Python3.11.14
torch2.9.0+cpu(镜像内置,与 torch_npu 配套,不得用普通 PyPI wheel 替换)
torch_npu2.9.0(镜像内置)
unidecode>=1.3.0(实测 1.4.0)
safetensors0.8.0

依赖安装

# 配置阿里云镜像(本环境已预设)
export PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
export PIP_TRUSTED_HOST=mirrors.aliyun.com

# 只安装非 torch 的应用依赖(torch / torch_npu 使用镜像自带版本)
pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt

requirements.txt 仅包含 unidecode>=1.3.0、safetensors>=0.4.2(纯应用依赖,阿里云镜像可用)。 不要安装或替换 torch / torch_npu。


分步推理操作流程

0) 进入交付目录

cd /work/pipeline/jobs/other40/vn-address-normalizer/vn-address-normalizer-npu

1) 确认 NPU 环境(可选)

npu-smi info          # 应看到 8 张 910B4-1,目标物理卡 npu:6 状态 OK
python3 -c "import torch, torch_npu; print(torch.npu.is_available(), torch.npu.device_count())"
# True 8

2) 语法自检

python3 -m py_compile inference.py scripts/*.py   # 应无输出、退出码 0

3) 运行端到端 NPU 推理(固定 npu:6)

export VN_ADDR_MODEL_DIR=/work/pipeline/models/other40/vn-address-normalizer
export NPU_DEVICE=npu:6
HOLD=22 scripts/run_npu_inference.sh \
  "p tan dinh q1 tphcm" "Phuong Ba Dinh Ha Noi" "Xa Cu Chi TP HCM" \
  "P. Bến Nghé Q.1 HCM" "phuong 14 quan 10 tphcm" \
  "duong le loi phuong ben nghe q1 tphcm"

scripts/run_npu_inference.sh 会:先做 npu-smi 基线采样 → 以 --device npu:6 --hold 22 启动真实推理并写入 logs/npu_inference.log → 并发采样 npu-smi 写入 logs/npu_device_call.log(PID/HBM/AICore)→ 等待结束后记录 EXIT_CODE 并做 退出后采样。--hold N:在模型就位后保持 NPU 上下文 N 秒,便于并发 npu-smi 抓取 进程 PID 证据。NPU_DEVICE 缺省为 npu:6(本机固定目标物理卡)。

也可以直接单条运行:

export VN_ADDR_MODEL_DIR=/work/pipeline/models/other40/vn-address-normalizer
python3 inference.py "p tan dinh q1 tphcm" --device npu:6

4) 结果文件

文件内容
logs/npu_inference.log原始推理日志(设备/版本/放置/输出/耗时/退出码)
logs/npu_result.json机器可读结果(顶层含 output、results、权重 SHA256)
logs/npu_device_call.log并发 npu-smi 进程证据(PID 在物理 NPU 6 上,HBM/AICore)

完整测试用例

测试输入:模型卡公开示例(6 条越南地址,含缩写、无音调、字母大小写混合、数字坊、 街道+坊组合等多种形态)。来源为模型源仓库 qox/vn-address-normalizer 的模型卡公开 输入/输出示例,license MIT。

执行命令(本轮最终验收运行,2026-08-22T19:47Z,物理 npu:6):

export VN_ADDR_MODEL_DIR=/work/pipeline/models/other40/vn-address-normalizer
export NPU_DEVICE=npu:6
HOLD=22 scripts/run_npu_inference.sh "p tan dinh q1 tphcm" "Phuong Ba Dinh Ha Noi" \
      "Xa Cu Chi TP HCM" "P. Bến Nghé Q.1 HCM" \
      "phuong 14 quan 10 tphcm" "duong le loi phuong ben nghe q1 tphcm"

实际输出(来自 logs/npu_inference.log / logs/npu_result.json,真实 NPU 运行):

==============================================================================
VN Address Normalizer - Ascend NPU inference
==============================================================================
  pid                     : 3608571
  engine                  : torch_npu
  hardware_name           : Ascend910B4-1
  npu_available           : True
  npu_count               : 8
  requested_device        : npu:6
  physical_device         : 6
  assigned_device         : npu:6
  cann_version            : 8.5.1
  driver_version          : 25.5.1
  torch_version           : 2.9.0+cpu
  torch_npu_version       : 2.9.0
  mha_fastpath_enabled    : False
  pinned_revision         : 5d0de6d07356774e861f72684e4807bdbc137351
  model_weight_sha256     : 4fcaae4f7a2e725aad234533e579884daa227c761b82c1c6a82c7ff73bbc2e3a
  model_parameters        : 6589197
  src_vocab_size          : 287
  tgt_vocab_size          : 269
------------------------------------------------------------------------------
  model.parameters device : npu

  Input:       p tan dinh q1 tphcm
  Canonical:   Phường Tân Định, Thành phố Hồ Chí Minh
  Valid:       True
  Input dev:   npu:6   Model dev:   npu:6
  Enc out:     [1, 128, 256] @ npu:6
  Dec logits:  [269] @ npu:6
  ...
  total_elapsed_s : 4.798
  peak_npu_mem_mb : 48.712
  exit_code       : 0
==============================================================================

6 条测试用例的实际结果(完整字段见 logs/npu_result.json):

#输入规范化输出Validconfidencelatency(ms)
1p tan dinh q1 tphcmPhường Tân Định, Thành phố Hồ Chí MinhTrue-5.93521588.9
2Phuong Ba Dinh Ha NoiPhường Ba Đình, Thành phố Hà NộiTrue-2.37271454.5
3Xa Cu Chi TP HCMXã Củ Chi, Thành phố Hồ Chí MinhTrue-1.11611273.2
4P. Bến Nghé Q.1 HCMPhường Sài Gòn, Thành phố Hồ Chí MinhTrue-30.4039193.8
5phuong 14 quan 10 tphcm(未找到)False0.04.0
6duong le loi phuong ben nghe q1 tphcmPhường Sài Gòn, Thành phố Hồ Chí MinhTrue-43.8763193.9

并发 npu-smi 进程证据(PID 在物理 NPU 6 上,见 logs/npu_device_call.log):

### npu-smi DURING run - process 3608571 captured on physical NPU 6 (sample 5, 2026-08-22T19:48:11Z)
	NPU ID                         : 6
	Chip Count                     : 1

	Process id:3608571 Process name:python3           Process memory(MB):110
	Chip ID                        : 0

SAMPLE=6 ... hbm=3456 aicore=0 proc_pid=3608571
SAMPLE=12 ... hbm=3576 aicore=10 proc_pid=3608571
  • HBM 采样:基线 3399 MB → 峰值 3576 MB(delta +177 MB)→ 结束后 3400 MB。
  • AICore 峰值:10%(beam search 前向)。
  • PID 关联:container_pid=3608571 == host_pid=3608571(共享 PID 命名空间), 与 logs/npu_result.json 的 pid 一致。

输出结果

  • 6/6 条模型卡示例完成推理;其中 5 条 Valid=True(含 1 条「Bến Nghé → Sài Gòn」的 2025 前区划名映射),1 条 Valid=False(数字坊 phuong 14 在 2025 后区划中已撤销, 与上游行为一致)。
  • 全流程放置断言:input_device=npu:6、model_device=npu:6、output_device=npu:6、 logits_device=npu:6;编码器输出 [1,128,256] @ npu:6,解码器 logits [269] @ npu:6。
  • 顶层字段:exit_code=0、engine=torch_npu、npu_available=true、 requested_device=npu:6、physical_device=6、npu_device_name=Ascend910B4-1, output 为非空对象(含 6 条标准化地址结果),并保留 results 与权重 SHA256。
  • 引擎证据:hardware_name=Ascend910B4-1、cann_version=8.5.1、torch=2.9.0+cpu、 torch_npu=2.9.0。
  • 性能:总耗时 4.798 s(含 6 条输入的冷启动 + trie 构建),峰值显存 48.712 MB, 退出码 0。

交付物清单

inference.py               # 自包含 NPU 推理脚本(fail-closed,无 CPU 回退,固定 npu:6)
readme.md / README.md      # 本文档(字节相同)
requirements.txt           # 非 torch 应用依赖(unidecode, safetensors)
.gitignore                 # 忽略字节码/缓存/权重/密钥/临时文件
scripts/run_npu_inference.sh  # 规范化推理 runner(npu-smi 并发采样)
scripts/monitor_npu.py        # npu-smi 采样器(PID/HBM/AICore)
scripts/render_assets.py      # 从真实日志重绘四张证据图
scripts/validate_metadata.py  # 元数据交叉校验
assets/agent_workflow.png  # 工作流图(1440x1800)
assets/modelagent_live_session.png  # 实况会话图(1440x900,真实脱敏 transcript)
assets/npu_device_call.png # NPU 设备调用证据(1440x900)
assets/model_result.png    # 模型结果图(1440x900)
logs/npu_inference.log     # 原始推理日志
logs/npu_result.json       # 结构化结果(顶层 output + results + 权重 SHA256)
logs/npu_device_call.log   # 并发 npu-smi 进程证据
logs/agent_workflow.log    # 工作流命令记录
logs/modelagent_transcript.log / modelagent_live_session.log  # 脱敏会话 transcript
SHA256SUMS                 # 交付物校验和

故障排查与限制

  • torch_npu 导入失败 / torch.npu.is_available()==False:请 source /usr/local/Ascend/ascend-toolkit/latest/set_env.sh 并确认 CANN 8.5.x 与 torch_npu 2.9.0 配套;脚本此时会以非零码失败(fail-closed),不会回退 CPU。
  • 设备不在 npu:6:脚本断言 torch.npu.current_device()==6;如目标物理卡不同, 请用 NPU_DEVICE / --device 指定并确认该卡空闲(npu-smi info)。本交付不使用 ASCEND_RT_VISIBLE_DEVICES 映射,npu:<id> 即物理卡 id。
  • 权重哈希不匹配:请核对 sha256sum model.safetensors 是否等于 4fcaae4f7a2e725aad234533e579884daa227c761b82c1c6a82c7ff73bbc2e3a;脚本以非零码失败。
  • 词典文件:src_vocab.json / tgt_vocab.json 需位于 model_v3_final/(本交付已 包含恢复的真实词典)。
  • ML-only 模式:本交付使用神经网络模型,不依赖规则 FST 引擎;「街道+坊」输入中 街道成分的保留能力取决于上游模型本身(search_space=1 时按上游行为仅输出坊/社级)。
  • 镜像:仅使用阿里云镜像安装非 torch 依赖;不要用普通 PyPI 轮子替换镜像自带的 torch / torch_npu 配套。

License

  • 模型权重与代码:MIT(qox/vn-address-normalizer)
  • 测试输入:模型卡公开示例(MIT)