大模型推理国产推理卡适配与性能调优落地

日期:2026-07-19

一、项目背景

这个项目里,我们服务的某省级政务单位与某头部金融机构(为脱敏,统称"客户")在信创合规要求下,必须把原先跑在进口 GPU 上的大模型推理服务,迁移到国产推理卡(如昇腾、海光等系列)构成的集群上。刚拿到第一批国产卡的时候,我们心里是打鼓的:一是算子层面不兼容,很多自定义算子在原厂框架里跑得好好的,换到国产卡的软件栈上直接报错;二是精度掉点,同样的权重、同样的输入,输出在某些任务上肉眼可见地变差;三是性能不达预期,单卡吞吐只有同价位进口卡的六成左右,离业务方要的并发量差得远。

我们当时定的目标很明确:在保证业务可接受的精度前提下,把算子兼容率、推理吞吐、部署周期都拉到一个能落地的水平。底座侧我们采用的是包含 vLLM/TGI 类推理框架、向量库与算力调度监控层的私有化 AI 部署底座,但推理后端必须适配到国产卡的软件栈,这就成了整个项目的技术主线。需要说明的是,本文只谈工程适配与调优经验,不涉及任何具体厂商的产品对比。

二、落地场景

整个落地覆盖了从权重到服务的全链路:

其一,模型权重转换。把原始 HuggingFace 权重转换为国产卡推理引擎支持的格式(如 OM/自定义 bin),并处理 dtype、分片、张量名映射等差异。

其二,算子对齐。逐层核对模型中用到的算子,对国产卡不支持或行为不一致的算子做等价替换或自定义实现,并沉淀一份可复用的算子兼容清单。

其三,图优化。利用图融合、常量折叠、KV 缓存优化等手段提升单卡效率,缓解显存压力。

其四是国产卡集群推理服务化与监控。把多卡多机组织成推理服务集群,前端通过我们采用的 AI 网关统一接入(兼容 OpenAI 风格协议),用 Prometheus + Grafana 监控吞吐、延迟、显存利用率,并对异常做限流熔断,形成算力—流量联动闭环。

三、关键技术挑战与解决思路

这个项目里我们主要啃了四块硬骨头。

第一是权重与算子适配。转换工具对主流模型支持还行,但对我们用的一个垂直领域 13B 模型,转换后直接崩在 layer 12 的 RMSNorm。我们的做法是先写一个小脚本逐层 dump 中间张量,定位到是某个自定义算子名称映射缺失。补上映射后,又遇到有几个算子国产卡软件栈尚未实现,我们改用等价的组合算子(比如把 fused attention 拆成 qkv 投影 + 标准 attention 再在框架侧融合)绕过,并做好算子兼容清单。最终算子兼容率从约 78% 拉到 97% 以上。

第二是精度对齐与掉点量化。这是最磨人的。我们不能只靠"肉眼看差不多",而是建立了一套量化对齐 pipeline:拿 2000 条业务域样本,分别在原环境和国产卡上跑,逐 token 比对 logits 的余弦相似度与 KL 散度,并统计下游任务(摘要、分类、抽取)的准确率偏差。最初 KL 散度达到 0.08,下游掉点约 4 个百分点,我们定位到是某算子的中间精度默认用了 fp16 而非 bf16,切到 bf16 后 KL 降到约 0.02,掉点收窄到约 1 个百分点,业务方才认可。

第三是图优化与显存利用。国产卡单卡显存相对紧张,13B 模型走 fp16 加长上下文时经常 OOM。我们的优化:一是开启 KV 缓存分页(paged attention),把显存碎片压下来;二是做算子融合减少中间激活占用;三是用连续批处理(continuous batching)提升 batch 利用率。调优后单卡能稳定承载的并发请求数提升了约 1 倍。

第四是异构集群调度。客户环境里其实是几代国产卡混布,算力与显存不一致。我们的解法是在调度层做算力画像,把不同型号的卡打上 tags,按模型大小与延迟要求路由到合适的卡组,并对弱卡组降低并发配额,避免长尾拖垮整体 P99。网关的路由层依据这些画像与实时配额做分发,弱卡组超阈值即触发限流,保护强卡组的稳定延迟。

案例片段(已脱敏): 权重转换与算子映射配置片段(简化): ```yaml

convert_config.yaml(脱敏示意)

src_format: hf          # 源:HuggingFace dst_format: om          # 目标:国产卡推理引擎格式 precision: bf16         # 精度,规避 fp16 掉点 tensor_name_map:  "model.layers.{i}.self_attn.qkv_proj": "layers.{i}.attn.qkv"  "model.layers.{i}.mlp.down_proj":       "layers.{i}.ffn.down" custom_op_replace:  - op: fused_rotary_emb    replace_with: [rope, mul]            # 该融合算子未实现,拆为等价组合  - op: fused_attention    replace_with: [qkv_proj, attention]  # 框架侧再融合 skip_unsupported: warn精度对齐采样脚本核心逻辑(伪代码):python for sample in calib_set:                 # 2000 条业务样本    ref = run_ref(sample)                # 原环境    tgt = run_target(sample)             # 国产卡    kl += kl_div(ref.logits, tgt.logits)    acc_diff += abs(ref.label == tgt.label) print(f"avg_KL={kl/len(calib_set):.4f}, acc_drop={acc_diff/len(calib_set):.3f}")

首轮输出: avg_KL=0.080, acc_drop=0.040

切 bf16 后: avg_KL=0.021, acc_drop=0.010

```

四、效果数据

适配与调优完成后,我们沉淀了一版对照数据(以下为脱敏示意值):

指标适配前调优后变化
算子兼容率约 78%约 97%提升至约 97%
推理吞吐 tokens/s(单卡)约 600约 1150提升至约 1.9 倍
精度对齐偏差(KL 散度)约 0.08约 0.02降至约四分之一
部署周期(单模型)约 3 周约 5 天降至约三分之一

集群侧,P99 延迟从约 1.8s 降至约 0.9s,弱卡组长尾被有效抑制;单卡可承载并发请求数提升约 1 倍,整体集群吞吐提升约 1.6 倍;资源利用率(显存与算力)从约 45% 提升到约 78%,基本告别空转。

五、可复用经验总结

这个项目最大的教训和收获都很清晰。

第一,先算子对齐再谈性能。我们一开始想直接上图优化冲吞吐,结果基础算子还没对齐,优化越多偏差越大。正确的顺序是:权重转换 → 算子兼容清单 → 精度对齐 → 最后才是图优化与显存调优。这个顺序后来成了我们团队适配新硬件的标准 SOP。

第二,精度掉点必须可量化,不能靠肉眼。建立一套 logits 余弦相似度 + KL 散度 + 下游任务准确率的三层对齐 pipeline,把"差不多"变成数字,才能和业务方有理有据地对齐验收标准。没有这把尺子,每次改配置都是在盲调。

第三,把转换配置和算子映射做成可复用清单。每适配一个模型,沉淀一份 convert_config 和 custom_op_replace 记录,后续同系列模型直接复用,部署周期从三周压到五天,靠的就是这份积累。异构集群的算力画像与路由策略也应沉淀为模板,新环境接入只需填表。

结语:国产推理卡的适配没有银弹,本质是把"精度可量化、算子可清单、性能可复现"这三件事做扎实。把转换配置、对齐脚本、调度画像都沉淀成资产,信创迁移就从一次性救火变成可复制的工程能力。