昇思学习营-模型推理和性能优化学习心得

55 阅读2分钟

学习心得:DeepSeek-R1-Distill-Qwen-1.5B 模型推理与性能优化(昇思 + 香橙派 AIpro)

经过完整实战,我把推理与优化心得提炼为“3 个性能指标、4 级优化手段、5 段关键代码、6 条避坑指南”,可直接作为后续项目 checklist。


一、3 个性能指标(在香橙派 20 TOPS 上实测)

指标基线(未优化)优化后提升倍数
首 token 延迟143 s(图编译)1.2 s(cache 复用)119× ↓
单 token 延迟1.1 s0.32 s3.4× ↓
峰值内存6.8 GB3.2 GB2.1× ↓

结论:边缘端跑 1.5 B 模型完全可以“秒回”,只要编译一次、缓存常驻即可。


二、4 级优化手段(层层递进,可独立生效)

级别手段收益一句话口诀
L0 环境cgroup 限制 Python 进程 + swap显存多 2 GB“先锁内存,再谈性能”
L1 框架禁用动态图多线程单 token 从 1.1 s → 0.67 sdisable_multi_thread() 三板斧
L2 编译@jit 图编译 + StaticCache0.67 s → 0.32 s“一次编译,永久躺平”
L3 算子Top-p 采样 numpy 实现 + RotaryEmbedding 重写再降 10 %“算子不快,就自己写”

三、5 段关键代码(复制即可用)

  1. 一键关多线程

    from mindspore._c_expression import disable_multi_thread
    disable_multi_thread()
    
  2. StaticCache 预分配

    from mindspore.nn import StaticCache
    cache = StaticCache(
        config=config,
        batch_size=1,
        max_cache_length=2048,
    )
    
  3. JIT 装饰 decode 函数

    @mindspore.jit(mode="O2", jit_level="O2")
    def decode_one_token(model, cur_token, position_ids, cache_position, past_kv):
        logits = model(cur_token, position_ids, cache_position=cache_position, past_key_values=past_kv)
        return logits
    
  4. Top-p 采样 numpy 加速

    def sample_top_p(probs, p=0.9):
        probs_np = probs.asnumpy()
        sorted_idx = np.argsort(-probs_np)
        cumsum = np.cumsum(probs_np[sorted_idx])
        mask = cumsum - probs_np[sorted_idx] > p
        probs_np[sorted_idx[mask]] = 0
        probs_np /= probs_np.sum()
        return mindspore.Tensor(probs_np).multinomial(1)
    
  5. 推理时间打点脚本

    export INFERENCE_TIME_RECORD=True
    python inference.py
    # 输出每 token 耗时,方便 A/B 对比
    

四、6 条避坑指南

坑点现象解决
1. pad_token=eos_token 导致 attention_mask 报警长文本重复 <think>手动传 attention_mask
2. 首 token 超慢每次都重新构图StaticCache 提到全局,只编译一次
3. jit 后显存反而涨O2 整图下沉占 workspace适当降低 max_cache_length
4. Top-p 用 mint.gather 报错aclnnGatherGetWorkspaceSize failed用 numpy 实现 or 回退到 mindspore.ops.gather
5. 多并发推理崩溃多进程竞争 NPU context加锁或改用单进程多线程
6. 温度=0 输出截断logits 全为 inf温度设极小值 0.01 替代 0

五、个人反思与下一步

反思下一步行动
只优化单卡单线程,利用率低用 MindSpore Serving + batch=4 做流水线
长文本 2048 后掉速尝试 StreamingLLM 动态 cache 丢弃策略
无系统化基准建立“首 token + 吞吐 + 功耗”三维基准板,持续追踪

一句话总结

“边缘端推理,慢的不是算力,而是编译与内存;把图焊死、把内存锁死,1.5 B 也能在 20 TOPS 上起飞。”