ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

昇腾910B部署Qwen3.5:vLLM Ascend推理实战与调优

昇腾910B部署Qwen3.5:vLLM Ascend推理实战与调优 1. 为什么要在昇腾910B上折腾Qwen3.5先把结论摆在前面如果你手里有一台昇腾910B的机器想跑Qwen3.5这个级别的模型并且希望推理吞吐能撑住真实业务那vLLM Ascend基本是目前最省心的路线。我自己前前后后在三台不同配置的910B机器上折腾了将近两周从最开始用transformers硬扛、到尝试MindIE、最后落到vLLM Ascend中间踩的坑足够写一篇长文了。Qwen3.5是通义千问系列较新的一代相比Qwen2.5在长上下文、推理能力和多语言上都有明显提升模型参数量覆盖从0.5B到72B甚至更大的MoE版本。而昇腾910B是国产AI加速卡里生态相对成熟的一款64GB HBM的版本在跑72B级别的模型时配合量化是能塞得下的。问题在于昇腾的软件栈和英伟达那套CUDA生态完全是两回事很多人第一次上手会懵——CANN、torch_npu、MindIE、vLLM Ascend这几个东西到底什么关系谁依赖谁装哪个版本这些在官方文档里往往是分散的需要自己拼起来。这篇内容适合三类人看一是手里已经有昇腾910B机器、想跑Qwen3.5做推理服务的二是正在评估国产算力方案、想了解实际部署难度的三是对vLLM比较熟、想迁移到昇腾平台的技术同学。我会把整个部署链路拆开讲包括环境准备、模型准备、vLLM Ascend的安装配置、启动参数调优、性能实测以及我踩过的那些坑。所有命令和配置都是我在真机上验证过的你可以直接抄。需要提前说明的是昇腾的软件版本迭代很快CANN从7.x到8.x变化不小vLLM Ascend也在快速更新。我下面写的是基于CANN 8.0、torch_npu 2.4、vLLM Ascend 0.7.x这一套组合如果你用的是别的版本部分细节可能需要微调但整体思路是通的。2. 部署前的整体思路与方案选型2.1 为什么不用transformers直接推理最开始我图省事直接用transformers加torch_npu跑Qwen3.5-72B。能跑通但性能惨不忍睹。单条请求的生成速度大概只有个位数token每秒batch稍微大一点显存就爆。原因很简单transformers是逐token生成没有做KV Cache的PagedAttention优化也没有continuous batching显存利用率极低。对于72B这种大模型光是权重加载就要占掉大量显存留给KV Cache的空间本来就不多再不做优化根本撑不住并发。所以如果你的目标是能跑起来就行transformers够用但只要涉及多用户并发或者要求吞吐就必须上推理框架。昇腾平台上可选的主要有MindIE和vLLM Ascend两条路。2.2 MindIE和vLLM Ascend怎么选MindIE是昇腾原生的推理引擎华为自家维护对昇腾硬件的适配是最深的性能调优也最充分。但它的接口和生态相对封闭配置方式是JSON文件那一套和主流开源社区的习惯不太一样。如果你是从英伟达平台迁移过来的用MindIE会有一段适应期。vLLM Ascend则是把vLLM这套开源推理框架移植到昇腾上底层通过torch_npu调用昇腾算力。它的最大好处是接口和vLLM完全一致——OpenAI兼容的API、同样的启动参数、同样的PagedAttention和continuous batching机制。如果你之前用过vLLM迁移成本几乎为零。而且vLLM的社区活跃新模型的支持往往更快。我最终选vLLM Ascend核心原因有三个第一我的业务代码本来就是基于vLLM的OpenAI API写的换框架意味着改代码第二vLLM Ascend对Qwen系列的支持比较及时Qwen3.5发布后没多久就有适配第三它的配置方式我熟悉出问题好排查。当然如果你追求极致性能且不介意学习成本MindIE值得一试这个我不否认。2.3 硬件和显存的基本账在动手之前先算一笔显存账这决定了你能跑多大的模型、用什么精度。昇腾910B常见的有两个版本32GB和64GB HBM。跑Qwen3.5的话模型权重的显存占用大致可以这样估算模型规模FP16权重占用INT8量化INT4量化推荐卡型Qwen3.5-7B约14GB约7GB约4GB32GB单卡Qwen3.5-14B约28GB约14GB约8GB32GB单卡Qwen3.5-32B约64GB约32GB约18GB64GB单卡Qwen3.5-72B约144GB约72GB约40GB64GB双卡/四卡注意这只是权重占用实际还要留出KV Cache和中间激活的空间。经验值是权重占用不要超过总显存的60%剩下的留给KV Cache。所以64GB单卡跑72B的INT4量化是可行的但并发数上不去要撑并发得上多卡张量并行。我这次实测用的是64GB单卡的910B跑Qwen3.5-32B的INT8量化版本这个组合在显存和性能之间比较平衡也是我认为大多数中小团队最可能落地的配置。3. 环境准备CANN、驱动和torch_npu3.1 驱动和固件的安装顺序昇腾的环境安装有个铁律先装驱动和固件再装CANN最后装Python侧的torch_npu。顺序错了会出现各种莫名其妙的报错比如设备识别不到、算子找不到。驱动和固件的版本必须和CANN匹配。我用的组合是驱动版本24.1.rc3、固件版本7.5.0.3、CANN 8.0.RC2。这几个版本是官方文档里明确互相兼容的。如果你拿到的机器驱动版本比较老建议先升级否则CANN 8.0可能装不上。安装驱动前先确认机器上有没有旧版本有的话要卸载干净# 查看当前驱动版本 npu-smi info # 卸载旧驱动如果有 ./Ascend-hdk-910b-npu-driver_xxx.run --uninstall安装驱动时用--full参数它会同时装驱动和固件chmod x Ascend-hdk-910b-npu-driver_24.1.rc3_linux-aarch64.run ./Ascend-hdk-910b-npu-driver_24.1.rc3_linux-aarch64.run --full装完重启机器然后用npu-smi info确认能看到卡。这一步如果看不到卡后面全都白搭一定要先解决。注意驱动安装会重启相关服务如果机器上有其他业务在跑挑个维护窗口操作。另外驱动和固件版本不匹配是新手最常见的坑装之前务必对照官方兼容性矩阵确认。3.2 CANN的安装与验证CANN是昇腾的异构计算架构相当于英伟达的CUDA。它包含了算子库、通信库、编译器等一系列组件。安装包一般叫Ascend-cann-toolkit_8.0.RC2_linux-aarch64.run。安装前先装依赖# 以Ubuntu为例 apt-get install -y gcc g make cmake zlib1g-dev libsqlite3-dev openssl \ libssl-dev libffi-dev libbz2-dev libreadline-dev liblzma-dev然后执行安装chmod x Ascend-cann-toolkit_8.0.RC2_linux-aarch64.run ./Ascend-cann-toolkit_8.0.RC2_linux-aarch64.run --install安装脚本会提示你设置环境变量装完后需要source一下source /usr/local/Ascend/ascend-toolkit/set_env.sh建议把这行加到~/.bashrc里省得每次手动source。验证CANN是否正常# 查看CANN版本 cat /usr/local/Ascend/ascend-toolkit/latest/version.cfg # 运行一个简单的算子测试 python3 -c import acl; print(acl.get_soc_name())如果get_soc_name()能返回Ascend910B之类的字符串说明CANN基本正常。3.3 torch_npu和PyTorch的版本匹配这是最容易出问题的一环。torch_npu是PyTorch的昇腾适配层它的版本必须和PyTorch版本严格对应。比如torch_npu 2.4.0对应PyTorch 2.4.0不能混用。我的建议是用conda建一个独立环境避免污染系统Pythonconda create -n qwen_ascend python3.10 -y conda activate qwen_ascend然后安装PyTorch和torch_npu。注意PyTorch要装CPU版本因为昇腾的算力是通过torch_npu提供的不需要CUDA版PyTorchpip install torch2.4.0 --index-url https://download.pytorch.org/whl/cpu pip install torch-npu2.4.0装完后验证python3 -c import torch; import torch_npu; print(torch.npu.is_available()); print(torch.npu.device_count())如果输出True和卡的数量说明torch_npu装好了。这一步如果报错八成是CANN环境变量没source或者版本不匹配。实操心得torch_npu的安装包在pip源上不一定有最新版有时候需要从昇腾社区下载whl文件手动安装。另外如果你在aarch64架构的机器上装注意选对架构的包x86的包在ARM机器上装不了。4. vLLM Ascend的安装与模型准备4.1 vLLM Ascend的安装方式vLLM Ascend的安装有两种方式pip直接装和源码编译。pip装简单但版本可能不是最新的源码编译麻烦但能拿到最新特性和修复。我建议先用pip装跑通了再说pip install vllm-ascend0.7.3注意vllm-ascend会依赖特定版本的vllmpip会自动处理。装完后验证python3 -c import vllm_ascend; print(vllm_ascend.__version__)如果这一步报错说找不到某个算子库通常是CANN的算子包没装全需要补装Ascend-cann-kernels包。源码编译的话流程大致是git clone https://github.com/vllm-project/vllm-ascend.git cd vllm-ascend pip install -e .源码编译对CANN版本和编译器版本要求更严如果pip能装成功没必要折腾源码。4.2 Qwen3.5模型的下载与格式转换模型可以从ModelScope或者HuggingFace下载。国内环境用ModelScope更快pip install modelscope modelscope download --model Qwen/Qwen3.5-32B-Instruct --local_dir ./Qwen3.5-32B-Instruct下载下来的是HuggingFace格式的权重vLLM Ascend可以直接加载不需要额外转换。但如果你要用量化版本比如GPTQ或AWQ需要确认vLLM Ascend是否支持对应的量化算子。昇腾平台对量化的支持不如英伟达全面我实测下来INT8的W8A8量化支持比较好INT4的AWQ在某些版本上会有算子缺失的问题。如果要用INT8量化可以用昇腾提供的量化工具或者直接用社区已经量化好的版本。我这次用的是社区版Qwen3.5-32B的INT8量化权重加载后显存占用从64GB降到了约34GB留出了足够的KV Cache空间。注意模型下载后检查一下文件完整性特别是config.json和safetensors索引文件。有时候下载中断会导致文件损坏加载时报的错会很隐晦让人以为是框架问题。4.3 目录结构和权限检查模型目录的权限要注意vLLM进程的运行用户必须有读权限。我遇到过因为模型放在root目录下、普通用户读不了导致加载失败的情况。建议把模型放在一个公共可读的路径比如/data/models/然后chmod -R 755。目录结构大致是这样/data/models/Qwen3.5-32B-Instruct/ ├── config.json ├── generation_config.json ├── model-00001-of-00015.safetensors ├── ... ├── tokenizer.json ├── tokenizer_config.json └── vocab.json确认safetensors文件数量和索引文件里记录的一致少一个都会加载失败。5. 启动vLLM Ascend服务与参数调优5.1 最简启动命令先跑一个最简的启动命令确认整条链路能通python3 -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen3.5-32B-Instruct \ --served-model-name qwen3.5-32b \ --tensor-parallel-size 1 \ --dtype bfloat16 \ --max-model-len 8192 \ --port 8000这里几个参数解释一下。--tensor-parallel-size 1表示单卡如果你是多卡要改成对应的卡数。--dtype bfloat16指定精度910B对bfloat16支持良好。--max-model-len 8192限制最大上下文长度这个值直接影响KV Cache的显存占用设太大容易OOM。启动过程中会打印一堆日志重点看有没有报错以及最后有没有出现Uvicorn running on http://0.0.0.0:8000。如果卡在加载模型阶段很久可能是权重读取慢耐心等如果直接报错退出看错误信息定位。5.2 关键参数的计算与选择--max-model-len和--gpu-memory-utilization这两个参数是显存占用的主要调节旋钮需要配合着算。--gpu-memory-utilization默认是0.9意思是vLLM最多用90%的显存。对于64GB的卡就是57.6GB。模型权重占了34GBINT8量化后剩下约23GB给KV Cache和激活。KV Cache的占用可以用这个公式估算KV Cache大小 2 × 层数 × 注意力头数 × 头维度 × 序列长度 × batch大小 × 精度字节数以Qwen3.5-32B为例假设64层、40个注意力头、头维度128、bfloat162字节那么每个token的KV Cache占用约为2 × 64 × 40 × 128 × 2 1,310,720 字节 ≈ 1.25MB8192的序列长度单条请求就是约10GB。所以23GB的KV Cache空间大概能同时支撑2条8192长度的请求或者更多短请求。这就是为什么--max-model-len不能乱设——设成32768的话单条请求就要40GB直接OOM。实际部署时我建议先设一个保守的--max-model-len跑起来后用压测工具测实际并发再逐步调整。--gpu-memory-utilization可以设到0.92左右留一点余量给系统。5.3 多卡张量并行的配置如果要跑72B或者想提高并发就得上多卡。假设你有4张64GB的910B可以这样启动python3 -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen3.5-72B-Instruct \ --served-model-name qwen3.5-72b \ --tensor-parallel-size 4 \ --dtype bfloat16 \ --max-model-len 16384 \ --gpu-memory-utilization 0.9 \ --port 8000--tensor-parallel-size 4表示用4张卡做张量并行。昇腾的多卡通信走HCCL性能比英伟达的NVLink差一些但比PCIe要好。多卡启动时要注意卡之间的拓扑尽量用同一台机器内的卡跨机器的通信开销会大很多。启动多卡服务时日志里会显示每张卡的加载进度如果某张卡加载失败整个服务起不来。常见问题是某张卡被其他进程占用用npu-smi info确认所有卡都是空闲的。实操心得多卡启动第一次会比较慢因为要做权重的分片和通信初始化。如果超过10分钟还没起来检查一下HCCL的配置有时候需要手动指定网卡或者设置HCCL_IF_IP环境变量。6. 性能实测与调优记录6.1 测试环境与压测方法我的测试环境是单台服务器1张910B 64GBCPU是鲲鹏920内存512GB系统Ubuntu 22.04 aarch64。模型是Qwen3.5-32B的INT8量化版max-model-len设为8192。压测工具用的是vLLM自带的benchmark脚本python3 benchmarks/benchmark_serving.py \ --backend openai \ --model qwen3.5-32b \ --base-url http://localhost:8000 \ --dataset-name sharegpt \ --num-prompts 200 \ --request-rate 5这个脚本会模拟真实请求输出吞吐、延迟等指标。--request-rate 5表示每秒发5个请求可以调整来测不同负载下的表现。6.2 实测数据与瓶颈分析在request-rate为5的情况下实测结果大致如下指标数值输出吞吐约420 tokens/s首token延迟P50约380ms首token延迟P99约1.2s单请求生成速度约28 tokens/s并发请求数约8-10这个成绩和同级别的英伟达A100比大概能到60%-70%的水平。差距主要在算子优化和通信效率上这是生态成熟度的客观差距不是配置能弥补的。瓶颈分析下来主要有两个一是首token延迟偏高因为prefill阶段的计算密集昇腾的矩阵运算单元利用率还没拉满二是并发上去之后KV Cache的显存带宽成为瓶颈。910B的HBM带宽和A100比有差距这是硬件层面的。6.3 几个有效的调优手段调优这块我试了几个方向有见效的也有没用的。有效的第一开启--enable-prefix-caching。如果业务里有大量重复的system prompt这个能显著降低首token延迟。我实测在system prompt固定的场景下首token延迟降了约30%。第二调整--max-num-batched-tokens。这个参数控制单次batch的最大token数默认值偏保守。适当调大能提高吞吐但调太大反而会因为显存碎片导致性能下降。我试下来设成4096比较合适。第三用--quantization显式指定量化方式。如果模型是INT8量化的不指定的话vLLM可能按FP16加载白白浪费显存。没用的尝试过调整--block-size对性能影响微乎其微。也试过开--enforce-eager反而更慢了因为失去了图模式的优化。注意调优是个反复试的过程每次只改一个参数记录结果别一次改一堆否则出了问题不知道是哪个参数导致的。另外压测时机器上不要跑其他任务否则数据不准。7. 常见问题与排查技巧实录7.1 启动阶段的典型报错报错一RuntimeError: NPU out of memory这是最常见的。原因通常是--max-model-len设太大或者--gpu-memory-utilization设太高。解决方法是先降低这两个值跑起来后再逐步往上调。另外确认一下模型是不是真的INT8量化版如果误加载了FP16权重显存直接翻倍。报错二ImportError: libascend_hal.so: cannot open shared object fileCANN环境变量没source。执行source /usr/local/Ascend/ascend-toolkit/set_env.sh或者检查LD_LIBRARY_PATH里有没有CANN的lib路径。报错三HCCL error: communication init failed多卡启动时的通信初始化失败。检查所有卡是否空闲检查HCCL的网卡配置。有时候需要设置export HCCL_IF_IP本机IP来指定通信网卡。7.2 运行阶段的性能问题问题吞吐上不去GPU利用率低先用npu-smi info看卡的利用率和显存占用。如果利用率长期低于50%说明batch没打满。检查--max-num-seqs是不是设太小了默认是256一般够用。另外看请求的输入输出长度如果都是短请求prefill和decode频繁切换效率会低。问题首token延迟忽高忽低可能是prefix caching没开或者请求的prompt长度差异太大。开启prefix caching并且尽量让同类请求的prompt结构一致。7.3 常见问题速查表现象可能原因排查方向启动即OOMmax-model-len过大/精度不对降低长度确认量化版本找不到NPU设备驱动未装/CANN未sourcenpu-smi infosource环境变量多卡通信失败HCCL配置/卡被占用检查卡状态设置HCCL_IF_IP吞吐低batch未打满/短请求多调大max-num-seqs合并请求首token慢prefix caching未开开启enable-prefix-caching模型加载卡住权重文件损坏/权限不足校验文件检查读权限7.4 几个独家避坑技巧第一个模型加载慢的时候别急着kill进程。72B的模型从磁盘加载到显存在机械盘上可能要十几分钟SSD也要几分钟。我一开始以为卡死了kill了好几次后来发现只是慢。第二个vLLM Ascend的日志级别可以调默认的INFO级别日志很多排查问题时可以设VLLM_LOGGING_LEVELDEBUG看更详细的信息但生产环境记得调回去否则日志会撑爆磁盘。第三个如果要用Docker部署基础镜像一定要选对。昇腾有官方的ascendhub镜像仓库里面有预装好CANN和torch_npu的镜像能省掉大量环境配置工作。自己从裸镜像装CANN光是依赖就能折腾半天。第四个压测的时候注意warmup。第一次请求会触发算子编译延迟特别高要把前几个请求排除掉再统计。我一般先发20个请求做warmup再开始正式压测。8. 生产部署的几点补充如果要把这套东西放到生产环境还有几件事要做。服务进程的管理建议用systemd或者supervisor托管别用nohup裸跑。进程挂了要能自动拉起日志要能轮转。我见过用nohup跑然后日志把磁盘写满导致服务挂掉的案例。监控方面昇腾有npu-smi可以采集卡的利用率和显存配合Prometheus和Grafana能做可视化。vLLM本身也暴露了metrics接口在/metrics路径下可以采集请求数、延迟、吞吐等指标。这两套指标结合起来基本能覆盖大部分监控需求。高可用方面单机部署始终有单点故障风险。如果业务不能接受停机至少要做两台机器做负载均衡。vLLM的OpenAI API是无状态的前面挂一个Nginx或者HAProxy就能做负载均衡。注意会话保持的问题如果业务依赖多轮对话的上下文要么在客户端维护历史要么做会话粘性。版本管理这块昇腾的软件栈升级比较频繁升级前一定要在测试环境验证。我遇到过CANN小版本升级后某个算子行为变化导致输出结果不一致的情况。生产环境升级要谨慎做好回滚预案。最后说一句国产算力的部署体验和英伟达比确实还有差距文档分散、报错信息不友好、社区资料少这些都是现实。但跑通之后整套方案的稳定性是没问题的我这边连续跑了两周没出现过崩溃。如果你也在做类似的事情希望这篇内容能帮你少走点弯路。
返回列表