一、背景
HY-Embodied 0.5 官方代码默认依赖 CUDA 和 flash-attn,在 Ascend 910B 上需要把注意力路径替换为 torch_npu。本次完成两件事:
- 8 卡并行推理验证。
- 8 卡 20 步微调冒烟训练,验证训练完成后权重能够正常保存并重新加载。
当前环境信息:
- 服务器:Ascend 910B3 共 8 卡,每卡 64GB HBM。
- 容器:hy,Python 3.11.15。
- 软件:torch 2.8.0,torch_npu 2.8.0.post1,transformers 4.57.0。
- 模型:/data/models/HY-Embodied-0.5。
- 代码:/HY-Embodied/Hy-Embodied-0.5。
二、flash_attn 剔除与 torch_npu 替换
代码和依赖中已经不存在 flash_attn 引用,requirements.txt 也没有 flash-attn 包。
注意力实现位于 finetune/hunyuan_vl_mot/modeling_hunyuan_vl_mot.py,核心使用:
- 非打包 batch 使用 torch_npu.npu_fusion_attention,input_layout 为 BNSD。
- 数据打包训练使用 torch_npu.npu_fusion_attention,input_layout 为 TND。
- 通过 cu_seqlens 表达 packed sequence 边界,保证每个样本独立做因果注意力。
- 视觉 span 使用双向注意力,再写回整体输出。
推理入口 inference.py 使用 attn_implementation=eager,并直接加载到 npu 设备。
三、8 卡推理
先清空卡片上的历史程序,然后执行:
cd /HY-Embodied/Hy-Embodied-0.5
bash run_inference_8cards.sh
脚本会在 8 张 NPU 上各启动一个独立进程,每张卡都执行单图和 batch 推理。
结果:
| NPU | 结果 |
|---|---|
| 0 | 成功 |
| 1 | 成功 |
| 2 | 成功 |
| 3 | 成功 |
| 4 | 成功 |
| 5 | 成功 |
| 6 | 成功 |
| 7 | 成功 |
NPU0 示例输出:
Result: <answer>
This is a close-up, slightly high-angle shot of a white office...
Batch Sample 1: <answer>
Okay, here are the standard steps to open a fridge door:
日志位置:
/tmp/hy_infer_8card/npu0.log
...
/tmp/hy_infer_8card/npu7.log
四、8 卡训练与冒烟验证
训练脚本使用仓库自带的 tests/test_data_packing.json 作为冒烟数据集,DeepSpeed ZeRO-2,8 卡 torchrun。
训练脚本默认已还原为原始步数配置:不传 --max_steps,--save_steps 100000。本次验证为了控制时间,临时通过环境变量限制为 20 步。
启动命令:
cd /HY-Embodied/Hy-Embodied-0.5
RUN_NAME=debug_npu_8card \
OUTPUT_DIR=/data/models/HY-Embodied-0.5-npu8 \
bash finetune/scripts/debug_npu8.sh
训练关键参数:
| 参数 | 值 |
|---|---|
| 卡数 | 8 |
| max_steps | 默认不设置(原始配置),本次验证 20 |
| per_device_train_batch_size | 1 |
| gradient_accumulation_steps | 1 |
| deepspeed | zero2.json |
| 精度 | bf16 |
| gradient_checkpointing | True |
| save_strategy | steps |
| save_steps | 默认 100000(原始配置),本次验证 20 |
训练结果:
- 退出码:0。
- 总耗时:约 172.77 秒。
- train_loss:0.1719。
- 单步耗时:约 5.6 秒。
本次 20 步冒烟验证完成后,Transformers Trainer 自动保存了 checkpoint 和最终 HF 权重。
五、权重保存校验
输出目录:
/data/models/HY-Embodied-0.5-npu8-step20
保存内容:
checkpoint-20/
model-00001-of-00002.safetensors
model-00002-of-00002.safetensors
model.safetensors.index.json
trainer_state.json
...
model-00001-of-00002.safetensors
model-00002-of-00002.safetensors
model.safetensors.index.json
config.json
tokenizer.json
校验结果:
| 项目 | 结果 |
|---|---|
| safetensors 分片 | 2 个 |
| 索引张量数 | 978 |
| 分片 1 | 5,000,007,256 bytes,472 keys |
| 分片 2 | 3,065,167,368 bytes,506 keys |
| 模型类型 | hunyuan_vl_mot |
| 模型参数量 | 3,785,086,960 |
重新加载验证命令:
cd /HY-Embodied/Hy-Embodied-0.5
python - <<'PY'
import torch
from transformers import AutoModelForImageTextToText, AutoProcessor
out = "/data/models/HY-Embodied-0.5-npu8-step20"
processor = AutoProcessor.from_pretrained(out)
model = AutoModelForImageTextToText.from_pretrained(
out, torch_dtype=torch.bfloat16, attn_implementation="eager"
)
print("LOAD_OK", model.config.model_type, sum(p.numel() for p in model.parameters()))
PY
实际输出:
LOAD_OK hunyuan_vl_mot 3785086960
说明训练保存的 safetensors 可以直接被 Transformers 读取并重建模型。
六、数据集说明
本次使用的是 GitHub 仓库自带的冒烟测试数据:
/HY-Embodied/Hy-Embodied-0.5/finetune/tests/test_data_packing.json
共 14 条 packed 样本,格式为 id、image、conversations,conversations 内使用 human/gpt 角色。
GitHub 的 HY-Embodied-0.5 README 没有提供 HY-Embodied-0.5 专用微调数据集,也没有写明官方真实训练数据来源。README 中链接的 tencent/Hy-Embodied-0.5-VLA-Data 属于 HY-VLA-0.5 的 UMI 数据,与本次冒烟训练不是同一批数据。
因此本次结果只证明 8 卡训练和权重保存链路可用,不代表真实数据上的微调效果。
七、注意事项
- 冒烟数据中答案较短且重复,loss 很快接近 0,属于数据特征,不代表模型过拟合判断。
- 真实微调需要按相同 JSON 结构准备自己的数据,或转换为 packed 格式后再训练。
- 训练脚本已还原原始步数:默认不传 --max_steps,--save_steps 100000;如需短验证可设置 MAX_STEPS 和 SAVE_STEPS。
- 发布或更新博客后需要执行 CDN 缓存刷新,否则旧内容可能继续被缓存服务。
简记。







