VLAVision-Language-Action视觉-语言-动作模型在机器人、具身智能这类场景里越来越热但真正把它搬到端侧跑起来第一个绕不开的坎就是推理延迟。端侧设备算力、内存、功耗都受限VLA模型又往往是视觉编码器大语言模型动作头的复合结构前向推理动不动就几百毫秒甚至秒级这对实时控制来说完全是不可接受的。我最近一段时间都在折腾VLA在端侧的部署优化踩坑踩了不少也把目前主流的加速手段梳理过一遍总结出六类能真正落地、可量化的技术手段今天一次性展开讲清楚。这篇内容适合正在做VLA、多模态大模型端侧推理的工程师也适合想把机器人决策模型从云端挪到本地、追求低延迟响应的同学参考。1. 模型压缩把VLA的“肚子”先减掉一圈VLA之所以慢很大一部分原因是模型本身太大。一个典型的VLA模型比如带视觉塔加7B级别LLM主干的结构光权重就要十几个GB端侧设备根本装不下更别提实时跑。所以第一类手段是模型压缩目标是让模型变得更小、计算量更低同时尽量保住精度。1.1 量化FP16降到INT8、INT4延迟能掉一半以上量化是见效最快、工程上最成熟的手段。把权重的精度从FP16降到INT8理论计算量可以降低约一半实际在端侧部署后推理延迟普遍能下降40%到60%如果进一步用INT4甚至混合精度模型体积和推理速度还能再进一步优化。实际操作中我建议优先做PTQ训练后量化流程是先从测试集或者实际任务场景里收集200到500张代表性图像和对应的文本输入跑一遍模型前向记录每层激活值的分布用均方误差、KL散度或者熵最小化策略确定每个张量的量化尺度scale和零点zero point把量化后的模型导出成端侧引擎支持的格式比如ONNX INT8或TensorRT engine。这里有个很关键的细节VLA模型的视觉编码器部分和LLM部分的数值敏感度完全不一样。视觉塔的feature map对量化误差容忍度相对高可以直接用INT8但LLM部分尤其是attention里的Q、K、V以及最后的动作头量化后精度掉得特别明显。我实测过一个VLA模型全INT8量化后动作预测的准确率掉了将近5个点后来改成视觉塔INT8、LLM部分保持FP16的混合精度方案延迟只增加了不到15%准确率只掉了0.8%。所以强烈建议做通道级或者层级的混合精度量化别图省事一把梭。如果PTQ掉点严重就用QAT量化感知训练。做法是在训练时插入伪量化节点让模型在前向传播时模拟量化误差反向传播时用直通估计器更新权重。QAT能拿回大部分精度损失但需要额外的训练资源和时间适合模型本身还有微调空间的情况。1.2 结构剪枝与蒸馏结构性减重剪枝和蒸馏本质上是在动模型的“骨骼”和“知识”。结构剪枝比非结构化剪枝更适合端侧部署因为它能真正把计算图变小。常见的做法是对多头注意力机制里的冗余注意力头做重要性排序剪掉得分低的头对FFN前馈网络层做稀疏化限制到2:4结构化稀疏剪掉视觉塔里响应贡献低的通道。我实测过对7B VLA的LLM部分做20%的注意力头剪枝推理延迟能降10%到15%精度几乎没有损失。但要注意别剪过头一旦超过30%模型的动作预测就会出现明显漂移尤其是指令跟随类的任务。蒸馏的思路更直接用一个大VLA模型当教师蒸馏一个小模型当学生。学生模型的结构可以是更小的LLM比如0.5B到2B也可以是对视觉塔做了缩小的版本。蒸馏时不一定只对齐logits还可以让学生的中间特征对齐教师的视觉和语言表示这样能保留更多跨模态对齐信息。蒸馏后的模型往往能保留教师模型80%到90%的能力但推理速度提升3倍以上。2. 计算图优化与算子融合让每一层算得更快模型体积减下来之后第二类手段是计算图层面的优化。刚才模型压缩解决的是“算的东西太多”这里解决的是“算得太冗余、太啰嗦”。VLA模型结构复杂计算图在编译时有很多优化空间。2.1 图重写常数折叠、冗余消除、形状推导端侧推理引擎在加载模型时会先做一次计算图重写。常用的优化包括常数折叠把只依赖常量的子图直接预先算好替换成结果节点冗余消除删除输出没有被后续节点使用的死节点形状推导把动态shape张量尽可能在编译期推导成静态shape减少运行时shape判断开销。动态shape是VLA部署的大坑。PyTorch模型里视觉特征经过投影层后token长度可能因为输入分辨率变化而改变LLM部分的attention mask也经常是动态生成的。如果计算图保留了动态shape分支每次推理都要做shape推断和内存重分配性能会明显下降。我的做法是强制固定输入分辨率比如统一到224×224或者336×336把关键的shape全部在编译期锁死这样引擎才能做更激进的内存规划和算子融合。2.2 算子融合把多次访存合并成一次算子融合是端侧引擎里收益最稳定的优化之一。原理很简单把多个相邻算子合并成一个kernel减少中间结果的写回和重新读取降低显存带宽压力。VLA模型里最容易融合的组合是ConvBNReLU融合成单算子视觉塔里大量存在QKV投影的矩阵乘法合并为一个大的GEMM一次算出Q、K、V而不是拆成三个小GEMMAttention里的Softmax和QK^T分块计算融合LayerNorm和后面的线性层融合GELU激活和前面的矩阵乘法融合。实测下来光是把视觉塔里的ConvBNReLU融合掉视觉编码部分就能提速约20%到30%。LLM部分把QKV三个投影合并成一个GEMM整体也能再快10%左右。这些优化在TensorRT、MNN、TNN、NCNN的图优化阶段都是自动完成的但前提是你导入的模型必须是完整的、可被重写的。如果算子太新、引擎不认就会退化成一个个独立的kernel去跑速度瞬间崩掉。提示图优化阶段不要图省事用旧版本引擎。VLA模型里常有FasterTransformer、FlashAttention、RoPE这类新算子建议优先选用对新算子支持完善的推理引擎版本否则你会被迫回退到性能极低的基础实现。3. 推理引擎选型与系统适配到了端侧还要面临一个绕不开的决策用什么推理引擎。不同引擎对算子的覆盖度、后端加速能力、内存管理策略差异很大直接影响VLA模型在端侧的真实延迟。我实际对比过常见的几款端侧引擎结论如下3.1 主流端侧推理引擎横评引擎适用平台对VLA支持程度GPU/NPU加速优缺点TensorRTNVIDIA Jetson等强算子覆盖广GPU加速成熟性能最好但绑定CUDA只适合N卡平台MNNAndroid/iOS/嵌入式中上新算子需适配支持GPU和部分NPU移动端生态好多线程调度成熟TNN移动端为主中上跨平台较好GPU加速较好腾讯系算子较全适合移动端多平台NCNN全平台轻量中复杂模型需调优GPU较弱极度轻量适合非常受限的端侧ONNX Runtime全平台强能导入导出常见格式支持多数硬件生态广配合自定义算子可以打通全链OpenVINOIntel CPU/GPU中上Intel硬件加速强适合Intel系列的边缘盒子我自己最常用的组合是NVIDIA平台上用TensorRT移动端和通用嵌入式环境用MNN或ONNX Runtime。注意没有万能引擎关键看你目标硬件上哪个引擎的后端算子覆盖和kernel优化做得好。3.2 引擎适配的两个关键配置第一内存池和显存分配策略要显式配置。VLA模型在推理时视觉特征、LLM的KV cache、动作头的中间变量同时存在峰值内存很容易被顶到很高。MNN、TensorRT都允许你预先分配固定大小的内存池而不是每次推理动态申请。我实测在Jetson Orin上固定显存池之后峰值显存从5.2GB降到了3.8GB还省下了反复malloc的时间。第二线程调度要主动控制。端侧设备往往是大小核架构如果只靠引擎默认调度可能所有线程都被塞到小核上延迟会非常难看。最好把视觉塔的卷积计算绑到大核LLM部分的矩阵乘也绑到大核把内存拷贝这类IO型操作留给小核。有些NPU推理是异步提交任务线程绑核之后能显著降低整体抖动。4. 端侧硬件加速与异构调度模型压缩和引擎优化还是软件侧功夫真正要压榨延迟必须把端侧硬件的算力吃透。VLA模型包含不同计算特性的子网络天然适合异构计算视觉塔是卷积和矩阵运算密集型LLM是访存和矩阵乘密集动作头则多是轻量MLP。让不同硬件干各自擅长的活能进一步降低端到端延迟。4.1 CPU、GPU、NPU怎么分工在配置足够的端侧设备上我习惯这样分工视觉塔和LLM的矩阵乘法交给GPU或NPU因为这类设备对矩阵乘法的并行加速效果最好预处理缩放、归一化、padding留在CPU上因为数据量小且GPU/NPU处理这类操作反而有Launch开销动作头这种轻量层留在CPU上跑避免频繁切换硬件上下文。用NPU时要注意端侧NPU通常只接受定点输入而且输入数据的layout可能要求和CPU端不一样。VLA模型里的视觉特征是浮点张量先把浮点转成定点再送NPU存储和计算会更高效但转换本身也有开销。如果整个视觉塔推理时间小于5毫秒就不值得为了上NPU而做量化转换直接用GPU或CPU更快。真正的高效方案是让不同硬件并行工作。比如用双流水线CPU先做当前帧的预处理同时GPU/NPU去推理上一帧的视觉特征最后CPU汇集结果再输出动作。这样端到端的延迟就不再是各个阶段耗时的简单相加而是流水线上最慢那个阶段的上限。4.2 多核并行与异步推理在C侧做端侧部署时我会把推理封装成异步任务用标准的线程池调度auto visual_task pool.enqueue([this, frame] { return visual_engine_-infer(frame); }); auto action_task pool.enqueue([this, text_tokens] { return llm_engine_-infer(text_tokens); }); auto visual_features visual_task.get(); auto action action_task.get();这样做的好处是视觉塔推理和LLM的prefill计算可以重叠执行。VLA模型里视觉编码和语言理解本质上是两条并行路径把它们串行化执行等于白白浪费了算力。实测在8核ARM平台上这种并行方案能把端到端延迟降低25%到35%。注意异步并发一定得处理线程安全问题。多个引擎实例之间如果有共享权重只读访问可以安全并发但KV cache这类会动态改写的内存就得做隔离或者互斥否则会出现偶发的推理结果错误。5. 缓存与流式推理减少重复计算VLA模型一个很特别的地方在于它既有视觉流又有语言流而且两者在时序上高度关联。如果每一帧都从头到尾全量推理计算浪费特别严重。把缓存机制和流式推理用起来能省掉大量重复计算这是很多刚接触VLA部署的人容易忽略的优化方向。5.1 跨帧视觉特征缓存机器人和具身智能场景下摄像头拍摄的连续帧之间往往变化不大。如果环境静态比如机械臂在桌面上执行抓取任务视觉场景在几百毫秒内几乎没有变化。此时不需要每帧都重新跑视觉塔可以只在关键帧上计算视觉特征中间帧直接复用缓存的特征只有当检测到画面变化超过阈值时才重新推理视觉塔。在实际项目里我做了一个基于感知哈希的触发策略对当前帧计算一个低成本的感知哈希值与上一帧比较相似度超过90%就直接复用上一帧的视觉特征低于阈值才触发视觉塔推理。这样做之后视觉编码部分的平均耗时从28ms降到了9ms整体VLA推理延迟差不多改善了35%。这个策略的合理性在于VLA模型里的视觉塔通常只输出一个固定维数的特征向量给LLM只要这个向量变化不剧烈后续的跨模态交互结果不会受到太大影响。视觉缓存不会显著影响决策质量。5.2 KV Cache和流式LLM推理LLM部分和纯语言模型的优化思路是相通的KV cache一定得用好。VLA的LLM在解析视觉特征和生成动作指令时同样存在prefill和decode两个阶段prefill阶段一次性处理输入的视觉token和文本token计算开销大但可以并行decode阶段逐token生成前一步生成的结果继续作为输入此时Q矩阵在变但K和V不变。如果不做KV cachedecode阶段每算一个token都要把前面的K、V重新算一遍时间成本是O(n^2)。加上KV cache之后复杂度降到O(n)。VLA模型的视觉token数量很可观一般几百到上千个这个优化收益是数量级的。更进一步的优化是把KV cache量化从FP16降到INT8或FP8。直接省一半的缓存空间同时让带宽压力降低。绝大多数端侧LLM推理引擎对这一块已经做得很成熟但前提是你部署时把该选项打开别用默认关闭的配置。5.3 流式推理管线端侧部署VLA时我还会把推理管线改成流式结构。具体做法是把感知、推理、控制三个环节解耦各自跑在独立的处理循环里通过共享内存队列传递结果。比如视觉循环以30FPS的频率持续跑视觉塔推理循环只消费最新的视觉特征和指令控制循环负责把动作结果下发给执行器。这样即使某个循环偶发卡顿其他循环也能继续运行整体延迟的可控性会好很多。提示流式管线会让延迟的“平均表现”变好但也会引入输出抖动。控制类任务对抖动容忍度很低建议在控制循环里做一个最小输出间隔限制也就是控制频率上限保证执行器的指令流稳定避免机器人一卡一顿地抽搐。6. 端到端部署落地基准测试与问题排查前面几类技术都很美好真正把它们组合到一起时往往会遇到一堆细节问题。最后一部分我把自己的落地流程和踩坑记录整理出来给大家一个可直接参考的操作模板。6.1 延迟拆解与基准工具优化之前先得知道延迟花在了哪里。VLA的端到端延迟可以拆成四段感知、视觉编码、语言理解与动作头计算、控制下发。我通常会在C代码里用计时宏逐段埋点再打印P50/P95延迟#include chrono #define TIME_SCOPE(name) \ auto _start_##name std::chrono::high_resolution_clock::now(); \ defer([]{ \ auto _end std::chrono::high_resolution_clock::now(); \ std::cout #name : \ std::chrono::durationdouble, std::milli(_end - _start_##name).count() \ ms\n; \ })跑50次推理后统计分布你会发现大部分时候瓶颈高度集中在某一段要么视觉塔的卷积太慢要么LLM的prefill卡住要么内存分配抖得厉害。先定位瓶颈再针对性优化永远比盲目卷算子融合高效。为了对比优化效果我建议采用三组指标端到端P50/P95延迟模型内存峰值动作预测与真实轨迹的误差比如末端执行器位置的平均绝对误差。优化时以延迟为主要KPI但要在精度指标和监督下推进避免掉点过多导致模型不可用。6.2 常见问题清单现象可能原因解决思路同一模型在Jetson上慢但在PC上很快TensorRT引擎版本不匹配算子回退升级/降级TensorRT检查算子支持列表量化后动作输出乱跳动作头对量化误差太敏感或量化校准集不够动作头保持FP16扩大校准集到训练分布更接近的样本偶尔单次延迟特别高冒出500ms尖刺内存分配抖动、线程切换、NPU任务排队固定内存池绑核限制NPU任务并行数视觉缓存复用时动作抖动明显场景变化时缓存触发阈值过宽提高感知哈希的相似度阈值加入场景置信度判断并发推理结果偶发错乱KV cache或共享权重存在写冲突对KV cache做实例隔离不要在多线程间共享可变状态模型导入后算子数量异常多引擎没有做图重写和融合检查引擎配置开启图优化level或者手动做算子替换6.3 一点实操心得我有两个强烈建议。第一保留一个不使用任何加速技巧的baseline版本每次改动都对照着测。优化手段叠多了之后很容易出现“叠加效果不如预期”甚至互相冲突的情况。比如量化虽然减了体积但KV cache量化与视觉缓存叠加后偶发的精度下降可能变成很难排查的问题。有了baseline定位回归就快很多。第二优先做缓存和流水线。模型压缩、算子融合、引擎选型这一类“硬功夫”做得再好收益也是有上限的但缓存和流水线是针对VLA任务特点的优化属于我刚才实测里收益最大的部分而且改动成本可控几乎不牺牲模型精度。如果你时间紧张我建议先从这个方向入手再回头补压缩和引擎侧的功夫。最后想说一点个人体会VLA端侧部署没有什么银弹六类手段是一个组合拳不同硬件平台、不同模型规模下的收益差异非常大。最稳妥的做法是先搭好延迟基准再逐步引入每一类优化在每一步都验证精度和延迟的变化最后才能把VLA真正推向实时、可控、稳的端侧落地状态。