让大模型在昇腾NPU上“起飞”:vLLM-Ascend调试调优全攻略

一、引言

最近在玩昇腾NPU上的vLLM-Ascend项目。这个开源仓库挺有意思的,它是vLLM的硬件插件版本,专门为华为昇腾芯片优化,支持大模型的推理加速。我之前在部署一些LLM服务时,经常遇到性能瓶颈或者奇怪的精度问题,所以花了不少时间研究调试和调优。今天分享一下我的心得,重点是调试调优的经验技巧。希望对大家有帮助,如果你也是在折腾昇腾环境,不妨试试这些方法。

vLLM-Ascend的核心是让大模型推理在NPU上跑得更快、更稳。它支持像Qwen这样的模型,部署起来相对简单,但实际用的时候,总有地方需要调。比方说,内存溢出、推理速度慢,或者输出结果不对劲。这些问题不调优的话,服务就没法上线。我的经验是,从环境开始优化,然后用工具剖析问题,最后针对性调整参数。整个过程像修车,先检查零件,再试跑。

下面我分几个部分聊聊,先说基础优化,然后是调试工具的使用,最后分享一些实际案例。文章会配上流程图和截图,便于理解。所有操作基于Atlas 800系列NPU,CANN版本8.3以上,Python 3.11。


二、基础环境优化

调试调优的第一步,不是直接看代码,而是优化环境。环境不对,后面再怎么调都白搭。我在实践中发现,昇腾的性能很大程度上取决于OS和库的配置。以下是我的几点经验。

2.1 容器化部署

首先,容器化部署是必须的。用Docker跑vLLM-Ascend,能隔离环境,避免主机污染。启动容器时,要挂载NPU设备和相关库。命令大概这样:

export DEVICE=/dev/davinci0
export IMAGE=quay.io/ascend/vllm-ascend:v0.11.0rc3
docker run --rm \
  --name vllm-ascend \
  --shm-size=1g \
  --device $DEVICE \
  --device /dev/davinci_manager \
  --device /dev/devmm_svm \
  --device /dev/hisi_hdc \
  -v /usr/local/dcmi:/usr/local/dcmi \
  -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
  -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
  -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
  -v /etc/ascend_install.info:/etc/ascend_install.info \
  -v /root/.cache:/root/.cache \
  -p 8000:8000 \
  -it $IMAGE bash

运行后,进容器检查npu-smi,确保NPU识别正常。截图如下:

这张图显示了NPU的利用率和内存使用,如果没问题,就可以继续。

2.2 优化Python和pip

接下来,优化Python和pip。默认Python可能没启用LTO和PGO,这些能提升编译效率。我下载了优化的Python包安装:

mkdir -p /workspace/tmp
cd /workspace/tmp
wget https://repo.oepkgs.net/ascend/pytorch/vllm/lib/libcrypto.so.1.1
wget https://repo.oepkgs.net/ascend/pytorch/vllm/lib/libomp.so
wget https://repo.oepkgs.net/ascend/pytorch/vllm/lib/libssl.so.1.1
wget https://repo.oepkgs.net/ascend/pytorch/vllm/python/py311_bisheng.tar.gz

cp *.so* /usr/local/lib
tar -zxvf py311_bisheng.tar.gz -C /usr/local/
mv /usr/local/py311_bisheng /usr/local/python
# 然后设置软链接和PATH

安装后,pip用清华镜像加速:pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple。这样下载模型快多了。

OS层面,内存分配器很重要。默认的可能碎片化严重,我试过jemalloc和tcmalloc。jemalloc适合多线程:

apt update && apt install libjemalloc2 -y
export LD_PRELOAD="/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD"

tcmalloc更适合大内存场景:

apt install libgoogle-perftools4 libgoogle-perftools-dev -y
export LD_PRELOAD="$LD_PRELOAD:/usr/lib/aarch64-linux-gnu/libtcmalloc.so"

我对比过,用jemalloc后,推理内存使用降了10%左右。结果图见下:

这个柱状图显示了默认、jemalloc和tcmalloc下的峰值内存,jemalloc胜出。

torch_npu的优化也不能少。设置内存扩展:

export PYTORCH_NPU_ALLOC_CONF="expandable_segments:True"
export TASK_QUEUE_ENABLE=2
export CPU_AFFINITY_CONF=1

这些能减少内存碎片,提高任务调度效率。

CANN的HCCL优化针对通信。启用AIV模式:

export HCCL_OP_EXPANSION_MODE="AIV"

多节点时,还可以调HCCL_BUFFSIZE。我在8卡部署时,设成256,提升了并行效率。

这些基础优化后,服务启动就稳多了。记住,优化前先benchmark一下速度,再比对。


三、性能剖析工具

调优不是瞎猜,得用工具剖析。vLLM-Ascend有几个好用的剖析器,我常用msserviceprofiler和执行时长观测。

3.1 msserviceprofiler

先说msserviceprofiler。安装简单:pip install msserviceprofiler==1.2.2。

配置json文件,比如ms_service_profiler_config.json:

{
  "enable": 1,
  "prof_dir": "vllm_prof",
  "profiler_level": "INFO",
  "host_system_usage_freq": 10,
  "npu_memory_usage_freq": 10,
  "acl_task_time": 1,
  "timelimit": 60,
  "domain": "Request;ModelExecute"
}

设置环境:export SERVICE_PROF_CONFIG_PATH=ms_service_profiler_config.json。

然后启动服务:vllm serve Qwen/Qwen2.5-0.5B-Instruct --host 0.0.0.0 --port 8000 &。

发送请求后,数据存到prof_dir。分析命令:

msserviceprofiler analyze --input-path=./vllm_prof/xxxx --output-path=output

输出有chrome_tracing.json,用MindStudio Insight看。流程图如下:

这个流程图从配置到可视化,一步步清楚。MindStudio里,能看到时间线,红色块是瓶颈。比如,我发现ModelExecute域占时长70%,就知道模型forward慢。

时间线视图详见如下链接中的介绍:https://www.youtube.com/watch?v=lxjWiVuK5cA

3.2 执行时长观测

另一个工具是执行时长观测。设环境变量:export VLLM_ASCEND_MODEL_EXECUTE_TIME_OBSERVE=1。

跑推理脚本,比如offline_inference_npu.py。日志会打印:

Profile execute duration [Decode]:
[post process]: 14.17 ms
[prepare input and forward]: 9.57 ms
[forward]: 4.14 ms

我用这个定位post process慢,是因为采样参数top_p太高。调低后,速度Up 20%。

前后时长对比表如下,可以看出,这个表直观显示优化效果。

阶段默认 (ms)优化后 (ms)
post process15.0310.50
prepare input and forward10.008.20
forward4.423.80

如果想深挖operator,用acl_task_time=2,预载libmspti.so:export LD_PRELOAD=$ASCEND_TOOLKIT_HOME/lib64/libmspti.so。

这些工具帮我省了不少时间,推荐先剖析再调。


四、调试技巧

调试是调优的痛点,vLLM-Ascend常出精度问题,如NaN或输出乱码。我用MSProbe工具诊断。

安装:pip install mindstudio-probe==8.3.0。可视化加pip install tb_graph_ascend。

(1)配置config.json:

{
  "task": "statistics",
  "dump_path": "/home/data_dump",
  "rank": [],
  "step": [],
  "level": "mix",
  "async_dump": false,
  "statistics": {
    "scope": ["Module.conv1.Conv2d.forward.0", "Module.fc2.Linear.forward.0"],
    "list": ["relu"]
  }
}

启动服务用eager模式:vllm serve Qwen/Qwen2.5-0.5B-Instruct --enforce-eager --additional-config ‘{“dump_config”: “/data/msprobe_config.json”}’ &。

发送请求,dump到data_dump。准备问题dump和基准dump。

(2)比较用compare.json:

{
  "npu_path": "./problem_dump",
  "bench_path": "./bench_dump"
}

运行:msprobe graph_visualize --input_path ./compare.json --output_path ./graph_output。

然后tensorboard:tensorboard --logdir ./graph_output --port 6006。

在浏览器看,红色节点是差异大处。比如,我发现relu后有Inf,是因为输入scale不对。调整量化参数解决。

调试流程图如下,从准备到分析,步骤清晰。

TensorBoard视图如下,其中高亮了conv层差异,帮我快速定位

常见技巧:

  • 用L1 level先轻量扫一遍,再mix深挖。
  • scope限制范围,避免dump太大。
  • 分布式时,指定rank。
  • 如果no dump,查权限或eager模式。

我调试一个Qwen模型时,用这个找到KV cache溢出,改kv_parallel_size后稳了。


五、调优案例

5.1 案例1:单卡推理慢——基于Profiling数据的内存优化

问题现象: 在部署Qwen2.5-0.5B模型时,设定batch=4,发现推理速度不理想,仅有 50 tokens/s 左右,且显存占用波动较大。

工具分析(关键步骤): 为了找到慢的原因,我使用了第三节介绍的 msserviceprofiler 进行抓取。

  1. 配置 ms_service_profiler_config.json,将 profiler_level 设为 INFO
  2. 运行推理并生成 chrome_tracing.json
  3. 数据解读:将文件导入 MindStudio Insight 或 Chrome://tracing 查看 Timeline。

下图展示了优化前的Profiling时间轴(红色箭头指向处展示了明显的调度间隙(Gap),表明NPU在等待CPU进行内存调度,并未满负荷工作)。可以看到在两个ModelExecute(模型计算)块之间,存在较长的空白间隙(Gap)。通过查看详情,发现这些间隙主要消耗在内存申请和释放的操作上,并没有在这个时间段内高效利用NPU计算单元。

我们通过分析认为这是默认内存分配器导致的内存碎片化问题,导致调度器花费大量时间在整理内存上。因此,我采取了前文提到的“组合拳”:

  • 配置内存分割export PYTORCH_NPU_ALLOC_CONF="max_split_size_mb:250",减少大块内存的频繁切分。
  • 更换分配器:启用 jemalloc 替代默认的 ptmalloc,优化多线程下的内存并发分配。

优化验证: 重新配置后再次Profiling,Timeline上的空白间隙明显缩短,计算密度变大。最终测试推理速度提升至 80 tokens/s 左右,性能提升约60%。

下图展示了优化后的Profiling Timeline视图 启用jemalloc和优化内存配置后,调度间隙显著缩短,计算流更加紧凑,吞吐量随之提升。

5.2 案例2:多节点精度问题

8卡EP,输出不对。

用MSProbe dump,比对发现专家层weight grad有NaN。改–quantization ascend,加–enable-weight-nz-layout,解决。

日志截图(dump.json 片段)如下,显示min/max值异常。

调后,结果正常,精度从0.85到0.92。

另一个技巧:在large_scale_ep教程基础上,调–max-num-batched-tokens和–gpu-memory-utilization。默认0.9,我调到0.95,内存利用高,但别溢出。

多节点通信,查hccn_tool,确保连通。

hccn_tool -i 0 -ping -g address 192.0.0.2

这些案例让我体会到,调优是迭代的,先基线,再工具,再调整。


六、总结

vLLM-Ascend的调试调优,说难不难,关键是工具和经验。基础优化打底,剖析工具找问题,针对性调参数,就能出好效果。我的博客基于仓库文档和实际操作,如果你有更好方法,欢迎评论交流。昇腾开源社区挺活跃的,多看readme和教程,能少走弯路。

最后,推荐仓库:https://github.com/vllm-project/vllm-ascend。里面有更多例子。

注明:昇腾PAE案例库对本文写作亦有帮助。

【负荷预测】基于VMD-CNN-LSTM的负荷预测研究(Python代码实现)内容概要:本文介绍了基于变分模态分解(VMD)、卷积神经网络(CNN)和长短期记忆网络(LSTM)相结合的VMD-CNN-LSTM模型在负荷预测中的研究与应用,采用Python代码实现。该方法首先利用VMD对原始负荷数据进行分解,降低序列复杂性并提取不同频率的模态分量;随后通过CNN提取各模态的局部特征;最后由LSTM捕捉时间序列的长期依赖关系,实现高精度的负荷预测。该模型有效提升了预测精度,尤其适用于非平稳、非线性的电力负荷数据,具有较强的鲁棒性和泛化能力。; 适合人群:具备一定Python编程基础和深度学习背景,从事电力系统、能源管理或时间序列预测相关研究的科研人员及工程技术人员,尤其适合研究生、高校教师及电力行业从业者。; 使用场景及目标:①应用于日前、日内及实时负荷预测场景,支持智慧电网度与能源化管理;②为研究复合型深度学习模型在非线性时间序列预测中的设计与实现提供参考;③可用于学术复现、课题研究或实际项目开发中提升预测性能。; 阅读建议:建议读者结合提供的Python代码,深入理解VMD信号分解机制、CNN特征提取原理及LSTM时序建模过程,通过实验调试参数(如VMD的分解层数K、惩罚因子α等)化模型性能,并可进一步拓展至风电、光伏等其他能源预测领域。
【轴承故障诊断】基于融合鱼鹰和柯西变异的麻雀化算法OCSSA-VMD-CNN-BILSTM轴承诊断研究【西储大学数据】(Matlab代码实现)内容概要:本文研究了一种基于融合鱼鹰和柯西变异的麻雀化算法(OCSSA)化变分模态分解(VMD)参数,并结合卷积神经网络(CNN)与双向长短期记忆网络(BiLSTM)的轴承故障诊断模型。该方法利用西储大学轴承数据集进行验证,通过OCSSA算法化VMD的分解层数K和惩罚因子α,有效提升信号去噪与特征提取能力;随后利用CNN提取故障特征的空间信息,BiLSTM捕捉时间序列的长期依赖关系,最终实现高精度的轴承故障识别。整个流程充分结合了智能化、信号处理与深度学习技术,显著提升了复杂工况下故障诊断的准确性与鲁棒性。; 适合人群:具备一定信号处理、机器学习及MATLAB编程基础的研究生、科研人员及从事工业设备故障诊断的工程技术人员。; 使用场景及目标:①解决传统VMD参数依赖人工经验选择的问题,实现自适应化;②构建高效准确的轴承故障诊断模型,适用于旋转机械设备的智能运维与状态监测;③为类似机电系统故障诊断提供可借鉴的技术路线与代码实现参考。; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点关注OCSSA算法的设计机制、VMD参数化过程以及CNN-BiLSTM网络结构的搭建与训练细节,同时可尝试在其他故障数据集上迁移应用以加深理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T-OPEN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值