大模型本地部署:端侧 LLM/VLM 实现机械臂自然语言指令控制

“把红色杯子拿给我”——这句人话,机械臂怎么听懂?答案是大模型。但云端 API 延迟高、断网就废,所以我们要把大模型塞进嵌入式板子里本地跑。

一、具身智能为什么要本地部署大模型

云端大模型 API(如 OpenAI、通义千问云端)确实强大,但具身智能场景有三个硬约束:

  • 延迟:机械臂需要毫秒级响应,云端一来一回动辄 500ms~2s,动作延迟感明显
  • 隐私:工厂/实验室内部数据不上云是合规底线
  • 断网可用:生产环境网络不稳定,断网就停机是不可接受的

本地部署解决这三个问题:推理在板子上跑,延迟可控、数据不出设备、断网照常工作。

二、端侧 LLM 选择

在 RK3588(8GB 内存)这类嵌入式平台上,大模型的选择受限于内存和算力:

模型 参数量 量化后内存占用 适用场景
Qwen2.5-1.5B 1.5B ~1GB(INT4) 指令解析、简单对话
Qwen2.5-3B 3B ~2GB(INT4) 复杂指令解析、任务规划
Llama3-8B-Quantized 8B ~4GB(INT4) 多轮对话、复杂推理
Phi-3-mini 3.8B ~2GB(INT4) 指令理解、代码生成

推荐首选Qwen2.5-1.5B3B。原因:中文能力强(Qwen 原生中文训练)、参数适中、INT4 量化后在 RK3588 上内存刚好够用、推理速度可接受。

三、端侧 VLM 选择

VLM(视觉语言模型)能"看图说话",让机械臂不仅能理解文字指令,还能理解摄像头画面:

模型 能力 嵌入式可行性
Qwen2-VL-2B 图像理解+文字对话 INT4量化后~1.5GB,RK3588勉强可跑
LLaVA-1.5-7B 图像描述+对话 INT4量化后~4GB,推理偏慢
InternVL2-2B 中文图像理解 量化后~1.5GB,中文场景优选

VLM 的价值:用户说"桌上有啥",VLM 直接分析摄像头画面回答"桌上有一个红色杯子和一个蓝色盒子",然后 LLM 再解析指令做动作规划——VLM 负责"看",LLM 负责"想"

四、RK3588 部署 LLM 方案

4.1 llama.cpp + RKLLM

llama.cpp 是轻量级 LLM 推理框架,纯 C/C++ 实现,支持 GGUF 格式模型:

Qwen2.5-1.5B (原版 HF格式)
    ↓ convert-hf-to-gguf.py 转换
GGUF 模型(支持多种量化级别)
    ↓ llama.cpp 推理
本地推理结果

瑞芯微官方还提供了 RKLLM SDK,针对 RK3588 NPU 做了专门优化,INT4 量化后推理速度比纯 CPU 快 3~5 倍。

4.2 MNN 推理框架

阿里开源的 MNN(Mobile Neural Network)也支持在 ARM 端跑 LLM:

  • 支持动态batch和KV Cache
  • 针对 ARM NEON 指令集优化
  • 支持 INT4/INT8 量化推理

方案选择:追求极致速度用 RKLLM(NPU加速),追求通用性用 llama.cpp(跨平台兼容),已用阿里生态用 MNN

五、模型量化:FP16 → INT4/INT8

量化就是降低模型参数的数值精度,用更少的位数存储和计算:

量化级别 内存占用 精度损失 推理速度
FP16 原始2倍参数字节 无损 最慢
INT8 参数字节减半 微损(<1%)
INT4 参数字节减至1/4 有损(2~5%) 最快

建议:指令解析任务对精度要求不高,INT4 完全够用。复杂推理任务用 INT8 保精度。

# llama.cpp 量化示例
python convert-hf-to-gguf.py /path/to/Qwen2.5-1.5B --outtype f16 --outfile qwen1.5b-f16.gguf
./llama-quantize qwen1.5b-f16.gguf qwen1.5b-q4_k_m.gguf Q4_K_M

六、自然语言指令解析

用户说 “把红色杯子拿给我”,LLM 需要将其解析为结构化任务:

原始指令: "把红色杯子拿给我"
    ↓ LLM 解析
结构化输出:
{
    "target": "红色杯子",
    "action": "抓取",
    "destination": "人面前",
    "priority": "normal"
}

关键点:LLM 输出不是自由文本,而是结构化 JSON——这样才能被下游程序解析并调用对应的运动规划 API。

七、Prompt Engineering 设计

系统提示词模板决定了 LLM 的输出质量和格式:

SYSTEM_PROMPT = """你是一个机械臂控制指令解析器。用户会给你自然语言指令,
你需要将其解析为结构化JSON格式。

输出格式要求:
{
    "target": "目标物体名称及特征(颜色、形状等)",
    "action": "动作类型(抓取/放置/推送/旋转)",
    "destination": "目标位置描述",
    "parameters": {
        "speed": "slow/normal/fast",
        "force": "light/medium/heavy"
    }
}

可选动作:抓取、放置、推送、旋转、指向
可选位置:人面前、桌面左侧、桌面右侧、桌面中心、指定坐标

只输出JSON,不要输出任何解释文字。"""

USER_INPUT = "把红色杯子拿给我"

# 组合prompt
full_prompt = f"{SYSTEM_PROMPT}\n用户指令:{USER_INPUT}\n输出:"

好的 Prompt 要做到:角色明确、格式严格、选项有限——让 LLM 在约束范围内精准输出。

八、指令到动作的映射

LLM 输出 JSON 后,程序解析并调用运动规划 API:

import json

def parse_and_execute(llm_output):
    """解析LLM输出JSON → 调用机械臂API"""
    try:
        cmd = json.loads(llm_output)
    except json.JSONDecodeError:
        print("LLM输出格式错误,无法解析")
        return False

    target = cmd["target"]        # "红色杯子"
    action = cmd["action"]        # "抓取"
    destination = cmd["destination"]  # "人面前"

    # 第1步:视觉检测目标
    obj_pose = vision_detect(target)  # YOLO检测 + 坐标转换

    # 第2步:运动规划
    if action == "抓取":
        trajectory = plan_grasp(obj_pose)
    elif action == "放置":
        target_pos = get_position(destination)
        trajectory = plan_place(obj_pose, target_pos)
    else:
        print(f"未知动作: {action}")
        return False

    # 第3步:执行
    robot_execute(trajectory)
    return True

九、代码示例:Python 调用 llama.cpp 推理 + 指令解析

from llama_cpp import Llama

# 加载量化模型
llm = Llama(
    model_path="qwen1.5b-q4_k_m.gguf",
    n_ctx=512,          # 上下文窗口长度
    n_threads=4,        # CPU线程数(RK3588有4个A72大核)
    temperature=0.1,    # 低温度=更确定性的输出
    top_p=0.9
)

SYSTEM_PROMPT = """你是一个机械臂控制指令解析器。将用户自然语言指令解析为JSON。
输出格式:{"target":"...", "action":"...", "destination":"..."}
可选动作:抓取/放置/推送/旋转。只输出JSON。"""

def parse_instruction(user_text):
    """自然语言指令 → 结构化JSON"""
    response = llm.create_chat_completion(
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_text}
        ],
        max_tokens=200
    )
    raw_output = response["choices"][0]["message"]["content"]
    try:
        return json.loads(raw_output)
    except json.JSONDecodeError:
        # LLM可能输出多余文字,尝试提取JSON部分
        import re
        json_match = re.search(r'\{.*\}', raw_output)
        if json_match:
            return json.loads(json_match.group())
        return None

# 测试
result = parse_instruction("把红色杯子放到左边")
print(result)
# 输出: {"target": "红色杯子", "action": "放置", "destination": "桌面左侧"}

十、RK3588 性能数据参考

配置 模型 量化 首 token延迟 掞理速度 内存占用
RK3588 CPU (4×A72) Qwen2.5-1.5B INT4 ~300ms ~15 tok/s ~1.2GB
RK3588 NPU (RKLLM) Qwen2.5-1.5B INT4 ~200ms ~25 tok/s ~1.0GB
RK3588 CPU Qwen2.5-3B INT4 ~500ms ~8 tok/s ~2.5GB
x86 (i5-12400) Qwen2.5-7B INT4 ~100ms ~30 tok/s ~4GB

1.5B 模型在 RK3588 上推理速度约 15~25 tok/s,一条指令解析通常只需 50~80 个 token,耗时 2~5 秒——对于机械臂任务规划来说完全可接受。

十一、本地部署 vs 云端 API 对比

对比维度 本地部署 云端 API
响应延迟 2~5秒(1.5B模型) 0.5~2秒(网络波动更大)
断网可用 可用 不可用
数据隐私 完全本地 数据上云
模型能力 1.5B~3B,够用但不强 GPT-4级,能力远超
成本 硬件一次性投入 按调用计费,长期成本高
部署难度 需要量化转换调试 API调用即用
升级迭代 需重新量化部署 服务端自动升级

结论:具身智能场景优先本地部署(延迟可控、断网可用),极端复杂任务可混合方案——简单指令本地解析,复杂推理云端兜底。


大模型从云端搬到家门口,机械臂才真正拥有了"自己的脑子"。模型够小、量化够狠、Prompt 写得够准,嵌入式端也能玩转自然语言控制。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐