7,652
社区成员
发帖
与我相关
我的任务
分享高通 QNN 转换大模型时提示算子分片内存溢出,拆分模型后依然内存报错,该如何分层优化模型加载与内存分配?
问题根因
算子分片溢出本质是单轮推理时,算子中间张量、权重、KV 缓存同时占用连续物理内存,单纯拆分网络层无法解决张量峰值内存叠加问题;同时 QNN 默认一次性预加载全部权重文件,启动瞬间内存冲击过大。
分步完整优化方案
开启权重分片按需加载配置
在模型转换 yaml 配置文件开启权重分块加载,避免一次性读取全部权重至内存:
# qnn_convert_config.yamlmodel_loading:weight_chunk_size: 128MB
lazy_weight_load: Trueunload_unused_weights: True
执行转换命令时绑定配置文件:
qnn-model-converter --input_model llm.onnx --config qnn_convert_config.yaml --output_model qnn_llm.bin
推理会话自定义内存池,限制峰值占用
C++ 参考代码,为推理会话划定独立内存上限,防止抢占系统内存:
// 初始化自定义内存池,最大分配2GB
Qnn_MemoryPool_Params pool_params;
pool_params.max_size = 2UL * 1024 * 1024 * 1024;
pool_params.allocation_strategy = QNN_MEM_POOL_STRATEGY_LIMITED;
Qnn_MemoryPool_Handle pool_handle;
QnnStatus ret = QnnMemoryPool_create(&pool_params, &pool_handle);// 绑定内存池至推理会话
session.bindMemoryPool(pool_handle);
算子粒度分片优化,拆分大张量算子
针对 Transformer 注意力、卷积等大张量算子,在转换时启用算子分片参数,将单算子计算拆分为多轮小块运算:
--graph_sharding_attention True --shard_tensor_max_size 64MB
运行时 KV 缓存动态回收
推理循环中增加缓存自动清理逻辑,对话轮次结束后释放过期 KV 张量:
def inference_loop(prompt_list):
session = get_qnn_session()for prompt in prompt_list:
res = session.run(prompt)# 单轮对话完成,释放当前KV缓存,不累积占用
session.clear_kv_cache()
session.release_memory_pool()
问题 1
问题 1:高通 QNN 转换大模型时提示算子分片内存溢出,拆分模型后依然内存报错,该如何分层优化模型加载与内存分配?
Question 1: Splitting the model still causes memory overflow errors when converting large models with Qualcomm QNN due to operator sharding, how to optimize layered model loading and memory allocation?
分类:AI 人工智能、生成式 AI
链接:CSDN 同事发布后回答,回答后粘贴;
回复:
问题根因
算子分片溢出本质是单轮推理时,算子中间张量、权重、KV 缓存同时占用连续物理内存,单纯拆分网络层无法解决张量峰值内存叠加问题;同时 QNN 默认一次性预加载全部权重文件,启动瞬间内存冲击过大。
分步完整优化方案
开启权重分片按需加载配置
在模型转换 yaml 配置文件开启权重分块加载,避免一次性读取全部权重至内存:
yaml
lazy_weight_load: Trueunload_unused_weights: True
执行转换命令时绑定配置文件:
bash
运行
qnn-model-converter --input_model llm.onnx --config qnn_convert_config.yaml --output_model qnn_llm.bin
推理会话自定义内存池,限制峰值占用
C++ 参考代码,为推理会话划定独立内存上限,防止抢占系统内存:
cpp
运行
// 初始化自定义内存池,最大分配2GB
Qnn_MemoryPool_Params pool_params;
pool_params.max_size = 2UL * 1024 * 1024 * 1024;
pool_params.allocation_strategy = QNN_MEM_POOL_STRATEGY_LIMITED;
Qnn_MemoryPool_Handle pool_handle;
QnnStatus ret = QnnMemoryPool_create(&pool_params, &pool_handle);// 绑定内存池至推理会话
session.bindMemoryPool(pool_handle);
算子粒度分片优化,拆分大张量算子
针对 Transformer 注意力、卷积等大张量算子,在转换时启用算子分片参数,将单算子计算拆分为多轮小块运算:
bash
运行
--graph_sharding_attention True --shard_tensor_max_size 64MB
运行时 KV 缓存动态回收
推理循环中增加缓存自动清理逻辑,对话轮次结束后释放过期 KV 张量:
python
运行
def inference_loop(prompt_list):
session = get_qnn_session()for prompt in prompt_list:
res = session.run(prompt)# 单轮对话完成,释放当前KV缓存,不累积占用
session.clear_kv_cache()
session.release_memory_pool()
参考资料
高通官方文档《QNN Large Model Memory Optimization Guide》,包含权重分片、内存池完整配置示例
行业技术文章《端侧大模型 QNN 部署内存溢出全流程排查方案》,覆盖算子分片、缓存管控、硬件调度全套落地流程