☰
JiuwenSymbiosis 远程推理接入指南:用 HTTP 视觉与语音服务让 Agent 主机脱离 GPU
2026/10/14 0:18:09 网站建设 项目流程
  • 具身智能
  • 人工智能
  • AI Agent
  • 机器人
  • 计算机视觉
  • Agent 编排

【免费下载链接】jiuwensymbiosis

Jiuwen Symbiosis就是一个"能懂人话、看得见物理世界、长了四肢的智能助手"。用户不需要示教,不需要教它怎么抓东西,怎么走路,就像指挥一个经验丰富的工人一样,用自然语言下任务,它就能自己完成感知、理解、规划、执行。

项目地址:https://gitcode.com/openJiuwen/jiuwensymbiosis
点击查看免费下载

JiuwenSymbiosis 支持把 GroundingDINO + SAM2、ASR 与 TTS 部署到独立推理服务器,通过固定的 HTTP/v1接口为 Agent 提供模型推理能力,从而让运行 Agent 的主机可以不配 GPU、不装模型运行时。本文完整讲解其核心概念、安装部署、视觉与语音配置、本地模型开关、旧配置迁移以及底层实现原理,读完后你可以在数十分钟内把一套「Agent 在瘦主机、模型在 GPU 服务器」的双机系统跑起来,并知道如何在真机上线前逐项验证延迟与故障语义。

核心概念:HTTP 推理服务、三种角色与两种托管形态

HTTP 推理服务与 sidecar 的边界

文档用「HTTP 推理服务」统称提供模型能力的远端进程,HTTP 只是通信方式。与之对应,「本地托管子进程(sidecar)」特指在detector.mode: local下由 Session 启动和停止的检测子进程。二者都走 HTTP 协议,区别在于进程所有者:

  • remote:服务由部署者独立管理(可以就在 Agent 本机手动启动),Agent 只管理自己的客户端连接,Session 退出时不会停止远端服务;
  • local:Session 负责启动、探测、回收模型进程,端口冲突会报错,绝不会把端口上未知的进程当作本 Session 的资源。

因此,即使服务就部署在http://127.0.0.1:8114本机回环地址上,只要进程不是 Session 托管的,就应使用remote模式接入——这也是没有 GPU 时最常使用的形态。

三个角色与数据流

远程化只改变模型执行的位置,机器人连接仍由 Agent 通过原有串口、USB、CAN、ROS 或 HTTP 适配器完成:

角色职责典型代码路径
Agent 主机输入采集、业务客户端、结果校验、三维几何、语音前端、任务编排与播报jiuwensymbiosis/perception/、jiuwensymbiosis/voice/、jiuwensymbiosis/agent/、jiuwensymbiosis/adapters/
推理服务接收有界输入、加载模型、排队推理、返回结果jiuwensymbiosis/serving/
本体与外设机器人控制器、相机、麦克风、扬声器原适配器驱动、AudioSource、AudioPlayer

视觉、ASR、TTS 可以分别部署在不同进程甚至不同主机,也可以共用同一个服务地址。Agent 通过固定的/v1接口调用,不需要 MCP,不需要选择协议版本(没有endpoint.protocol之类字段),也没有令牌、代理或自动跳转配置。

安装 Agent 与部署推理服务器

在 Agent 主机安装客户端

Agent 主机只需安装客户端与采集组件,不装模型运行时:

pip install -e ".[remote]" # 使用 RealSense 与本机音频采集/播放时,按需追加: pip install -e ".[remote,camera,voice-io]"
  • remote组只含 HTTP 客户端(httpx>=0.28)与图像编解码(pillow>=12),见 pyproject.toml;
  • 硬件 SDK 按适配器要求独立安装,例如 Piper 的.[piper]、SO-101 的.[so101];
  • 「无 GPU」不等于「每种适配器都能完全移除 Torch」:SO-101 的 LeRobot 组仍依赖 Torch/TorchVision;OpenJiuwen 的 Transformers 间接依赖也仍然存在,只是 HTTP 客户端不要求加载它;
  • 已有.[full]/.[voice]保留为本地模型依赖的兼容入口,远程 Agent不应为了使用 HTTP 客户端而安装它们。

在推理服务器准备环境与模型

服务器侧安装vision-server或speech-server及实际选用的模型组,并选择配套的 Torch/CUDA wheel(以下为 CUDA 12.8 示例,CPU 部署把索引换成https://download.pytorch.org/whl/cpu并在启动时使用--device cpu):

# 视觉服务器 python -m pip install torch==2.8.0 torchvision==0.23.0 --index-url https://download.pytorch.org/whl/cu128 python -m pip install -e '.[vision-server]' # ASR 服务器(可与视觉分开) python -m pip install torch==2.8.0 torchaudio==2.8.0 --index-url https://download.pytorch.org/whl/cu128 python -m pip install -e '.[speech-server,voice-local]' # TTS 服务器(必须使用独立环境,原因见下) python -m pip install torch==2.8.0 torchaudio==2.8.0 --index-url https://download.pytorch.org/whl/cu128 python -m pip install -e '.[speech-server,chattts-server]'

依赖冲突提醒:chattts-server固定 ChatTTS 0.2.4 + Transformers 4.53.3,而视觉服务需要transformers>=5,二者不能装进同一个 Python 环境。deploy/inference/compose.yaml的三个服务分别构建镜像,就是为了隔离这两套依赖。

模型权重需自行按发布方许可准备(服务端不替 Agent 下载权重),建议目录结构(非空目录,需含完整配置、分词器与权重):

/srv/jws-models/ grounding-dino/ # IDEA-Research/grounding-dino-base 的 Transformers 快照 sam2/ # facebook/sam2.1-hiera-large 的 Transformers 快照 paraformer/ # FunASR paraformer-zh 本地模型目录 chattts/ # ChatTTS 0.2.4 source=custom 完整目录(含 asset)

直接启动三个服务

python -m jiuwensymbiosis.serving.grounding_dino_sam2_server \ --host 127.0.0.1 --port 8114 --device cuda:0 \ --gdino-model-id /srv/jws-models/grounding-dino --sam2-model-id /srv/jws-models/sam2 python -m jiuwensymbiosis.serving.speech_server \ --host 127.0.0.1 --port 8115 --device cuda:0 \ --asr funasr --asr-model-path /srv/jws-models/paraformer python -m jiuwensymbiosis.serving.speech_server \ --host 127.0.0.1 --port 8116 --device cuda:0 \ --tts chattts --tts-model-path /srv/jws-models/chattts

一个 speech 进程也可同时指定 ASR/TTS,但默认不启用任何模型,必须显式选择。服务器默认绑定回环地址;跨主机部署时配置监听地址与端口(INFERENCE_BIND),客户端填写可访问的 HTTP 地址即可,无需令牌。视觉请求上限 16 MiB、最多 16,777,216 像素、最多 32 个目标;语音 CLI 可调整--max-queue、--queue-timeout-s等排队参数。

Compose 一键部署

从仓库根目录按需开启 profile,权重只读挂载、镜像不含权重:

export MODEL_ROOT=/srv/jws-models export MODEL_DEVICE=cuda:0 docker compose -f deploy/inference/compose.yaml -f deploy/inference/compose.gpu.yaml \ --profile vision --profile asr --profile tts up --build -d

GPU overlay(compose.gpu.yaml)为每个服务预留一张 NVIDIA GPU;CPU 验证时省略 overlay、设置MODEL_DEVICE=cpu与TORCH_INDEX_URL后重建。容器内置 healthcheck.py 以/v1/health验证服务类型与模型就绪,应用级就绪检查比 TCP 端口探测更可靠。完整启动命令、模型路径与限制见 推理服务部署说明。

配置远程视觉

保留原运行配置中的adapter、硬件连接、标定、LLM 与护栏字段,将检测配置替换为:

detector: mode: remote endpoint: url: https://inference.example/vision connect_timeout_s: 3 request_timeout_s: 30 max_frame_age_s: null # 可选:填写正数(秒)才启用额外的图像年龄限制

关键规则:

  • endpoint.url是唯一必填字段,值为服务基础地址(不含/v1/segment),客户端会追加路由;
  • 本地与远程统一使用/v1接口,无版本选择器;
  • 连接超时默认 3 秒,请求总超时默认 30 秒;客户端直接 HTTP 调用,无需配置令牌;
  • endpoint仅接受 HTTP(S) URL,且不允许携带用户名/密码、查询参数或 fragment(见 service_http.py)。

超时与图像年龄:max_frame_age_s的语义

request_timeout_s是一次请求的总时限(覆盖 JSON 编码、连接、读取与连接重试)。但 HTTP 返回早不等于结果仍适合执行动作——图像编码发生在 HTTP 客户端内,三维几何又发生在返回之后。因此框架提供从采集到结果可用的整条链有效期:

  • max_frame_age_s为null(默认)时不额外限制图像年龄;
  • 填写有限正数时,限制从采集开始到结果可用的总时间,包括同一帧的多次提示词请求、mask 解码与本地几何计算;
  • 实际 HTTP 请求预算取「请求超时」与「剩余帧有效期的较小值」;
  • 该规则适用于本地、远程与兼容入口;tracking 原有的 8 秒图像年龄上限仍独立生效,HTTP 超时不会放宽它(见 tracking.py 相关约束与 runner.py);
  • 年龄只在 Agent 单调时钟域内比较,不跨主机直接相减。

Python 兼容入口为init_detector(url, timeout_s=30, max_frame_age_s=None),需要时可把年龄上限设成正数(见 detector_client.py)。

三种显式模式与默认值

模式行为
remote调用endpoint;不启动模型进程、不检查本地权重
local启动并托管一个可选的本地模型进程;需要模型依赖
disabled不发送推理请求;检测调用明确报告不可用,采集与单点像素投影仍可用

没有检测配置时默认disabled。源码 DetectorConfig 中:disabled模式不得配置endpoint/local;remote必须有endpoint且不得配置local;local不得配置endpoint,且local.host强制为回环地址。检测失败与「成功检测但没有目标」严格区分:空结果detections: []是合法观测,连接失败、超时、服务未就绪则抛inference_unavailable/inference_timeout,远程失败不会自动加载本地模型兜底。采集、标定变换、深度投影与三维几何始终由 Agent 框架完成。

配置远程语音

将以下voice块合入同一份运行配置(可参考已整合的 remote-client.yaml):

voice: wake_enabled: true wake_command_timeout_s: 10 sample_rate: 16000 audio_backend: sounddevice asr: backend: remote endpoint: url: https://inference.example/speech request_timeout_s: 15 max_audio_duration_s: 30 max_command_age_s: 20 tts: backend: remote endpoint: url: https://inference.example/speech request_timeout_s: 30 voice: default playback_backend: sounddevice

将编辑后的完整配置保存为命令中的文件后启动:

jiuwensymbiosis-run --config configs/piper/piper.remote.yaml --voice

说明:仓库configs/piper/下出厂文件为piper.yaml,piper.remote.yaml需要你按上文合入detector与voice块后自行创建;也可以直接参考 remote-client.yaml 的完整片段。

远程语音的行为边界:

  • 录音与播放发生在 Agent 主机;远端 ASR 接收音频返回文本,远端 TTS 返回音频,均不访问机器人或 Agent 的麦克风/扬声器;
  • 语音循环是半双工的:上一轮反馈播放结束后才录音,播报期间不会把自己的声音识别成新任务;
  • 过期识别结果不派发动作(max_command_age_s默认 20 秒,源码见 loop.py 等处的年龄检查);
  • 播报失败不重跑已完成的任务,只记录反馈失败。

默认值:必须显式选择后端

  • ASR 默认disabled,TTS 默认null——仅填写模型名或 device不会隐式启用 FunASR;
  • 使用真实--voice采集前必须显式选择 ASR 后端;--voice-text可注入固定文本后端用于测试;
  • VoiceConfig 中:audio_backend默认pulse、sample_rate默认 16000 Hz、wake_command_timeout_s默认 10 秒、max_audio_duration_s默认 30 秒、max_command_age_s默认 20 秒、tts.voice默认default、playback_backend默认sounddevice、tts.queue_size默认 8、async_play默认true、max_text_length默认 2000 字符、tts.max_audio_duration_s默认 120 秒;
  • 后端为remote时不得配置本地模型参数(model/device/vad 等),违反会直接报错(见 config.py)。

按需启用本地模型

本地视觉与远程视觉共用同一个客户端结果契约(mask/box/score/label)。若 Agent 主机具备模型运行条件,可将检测配置改为:

detector: mode: local local: host: 127.0.0.1 port: 8114 device: cuda startup_timeout_s: 300 gdino_model_id: ./models/grounding-dino sam2_model_id: ./models/sam2 use_sam2: true
  • detector.local默认值:host=127.0.0.1、port=8114、device=cuda、startup_timeout_s=300、gdino_model_id=IDEA-Research/grounding-dino-base、sam2_model_id=facebook/sam2.1-hiera-large、box_threshold=0.35、text_threshold=0.25、use_sam2=true(见 config.py);
  • 模型 ID 解析规则:以./、../、~或绝对路径开头的值按配置来源目录解析为本地目录;Hub ID 保持不变;
  • 本地 FunASR:voice.asr.backend: funasr,并显式选择device: cpu或 CUDA 设备;
  • 本地 ChatTTS:voice.tts.backend: chattts,用module_path指向已有的兼容tts.py模块;
  • 选择这些后端前必须先安装对应依赖(voice-local/chattts-server等);CPU 可选不等于目标机器上的推理延迟已合格。

工作台与旧配置迁移

工作台(GUI)的视觉模式切换

工作台的「配置 → 视觉服务」支持模式切换(源码见 config_view.py 与 config_model.py):

  • 远程模式:显示 URL 与总超时,提供显式「检查远程服务」按钮,不弹出本地权重选择对话框;
  • 本地模式:显示模型、设备与启动参数;
  • 「禁用视觉服务」开关会覆盖新旧检测配置;
  • 标定与硬件维护会话不启动检测进程、不检查远端服务(维护会话只登记客户端清理,不发起推理 I/O)。

旧api_servers检测条目的迁移

旧配置仍处于兼容期,但只做归一化、通信统一使用当前/v1接口:

  • 显式spawn: false→ 转换为remote模式;其他旧检测条目按旧「本地启动」意图解析并告警;
  • 不要同时提供新detector块与旧检测条目——两者同时出现直接报冲突(见 config.py);
  • DetectorServerConfig保留 Python 构造兼容,init_detector(url)统一指向当前/v1接口;独立运行的旧版视觉服务需升级到提供该接口的配套版本;
  • 旧语音平铺字段(如asr_model)暂时可读,但同一后端不能混用新旧字段,应迁移到voice.asr/voice.tts。

部署后的验证与延迟测量

不连接本体的快速冒烟验证

在 Agent 环境(只需安装.[remote])运行 smoke.py,可只配置需要测的某一种远程后端:

python deploy/inference/smoke.py --config deploy/inference/remote-client.yaml python deploy/inference/smoke.py --config path/to/runtime.yaml \ --image path/to/scene.jpg --prompt 'cup' --audio path/to/command.wav \ --output-wav /tmp/jws-speech.wav
  • 不提供文件时使用固定红色矩形图与 1 秒静音;「无目标」「无识别文本」都是合法结果;
  • 脚本检查请求/响应身份、mask 与音频格式,不驱动本体、不打开麦克风、不播放声音;
  • 输入 WAV 必须是单声道 PCM16,采样率与服务器配置一致;
  • 一次冒烟成功只代表该组请求完成,不能据此推断持续控制频率、模型质量或真机表现。

就绪检查与分链路验收

  • 先以GET /v1/health确认服务身份与就绪状态(客户端DetectorClient.readiness()会校验service与status,见 detector_client.py);
  • 然后分别验证静态定位、连续跟踪与语音延迟:连续跟踪的网络预算比静态定位严格,一次静态成功不能外推;
  • 正式上线前在目标两台主机测量冷启动、稳定延迟、网络断连、排队超时与峰值内存/显存,并按任务调整max_frame_age_s与max_command_age_s;
  • 远程化只是把模型计算移出 Agent 主机,不保证跨网络的特定控制频率,实际频率取决于链路与服务器性能。

源码级实现原理:客户端调用链、传输层与接口契约

视觉调用链:从采集帧到机器人坐标

一次感知从 CameraFrame 开始:rgb发往检测服务;depth_m、intrinsics、tf_base_cam留在 Agent 供三维计算。DetectorClient.__call__(detector_client.py)为每次请求生成独立request_id,把 RGB 编码为 JPEG(Base64),携带frame_id与text_promptPOST 到/v1/segment。同一采集帧的多次提示词可共享frame_id,但各有独立request_id。服务端只收到 RGB 与文本,不收到深度、内外参或机械臂状态。

返回后客户端先校验版本、请求身份、帧身份与原图尺寸,再逐项校验框(原图像素 xyxy、须在图像内)、分数(有限且 ∈[0,1])与无损 PNG 二值 mask,最终得到与输入同尺寸的mask布尔数组。视觉服务端内部串联两个模型(见 grounding_dino_sam2_server.py):GroundingDINO 负责「找到与文本对应的候选框」,SAM2 负责「描述候选占据的像素区域」;--no-sam2模式用矩形框代替真实轮廓,只适合规则箱体。成功但无目标时返回detections: [];失败用非 2xx 状态和error: {code, message, retryable}信封表达,绝不用空数组掩盖故障。

传输层:单在途请求、绝对截止时间与可取消清理

三种 HTTP 客户端(视觉、ASR、TTS)共用 HttpServiceClient:

  • 每个客户端最多一个在途请求,并发请求返回inference_busy,不建立无界队列;
  • request_json以绝对截止时间约束:JSON 编码、连接、读取与(仅限httpx.ConnectError/ConnectTimeout的)一次重试都在总预算内;
  • 取消通过CancelToken.on_cancel送达真实 asyncio 任务,任务未创建时在启动等待路径立即完成工作登记,任务已执行时等待协程实际退出才移除登记——调用者先返回不代表清理已完成;
  • 请求体默认上限 16 MiB、响应上限 64 MiB;close()超时保留句柄与失败状态供所有者重试,绝不把 daemon 线程或 wait 超时当作资源已释放;
  • HTTP 客户端不识别模型方案:它不知道 perception、音频或机器人动作 schema(模块文档自述「does not know perception, audio, robot actions」)。

/v1接口契约速查

所有路由都相对于endpoint.url:

路由请求要点成功result
GET /v1/healthX-Request-ID请求头服务身份、就绪状态与能力/限额
POST /v1/segmentschema_version: 1、request_id、frame_id、JPEG/PNG、text_prompt、top_k同 frame_id、原图尺寸、detections(mask/box/score/label)
POST /v1/transcriberequest_id、utterance_id、单声道 PCM16 WAV同 utterance_id、text(允许null)
POST /v1/synthesizerequest_id、text、voiceWAV、sample_rate、channels、duration_s

成功信封统一为{"schema_version": 1, "request_id": "…", "result": …};ASR/TTS 请求体当前不包含schema_version,不要把响应字段直接复制进请求体。完整协议与示例 JSON 见 设计文档。

故障语义与资源所有权

情况当前处理
成功的空检测无目标观测,是感知循环正常结束的依据
成功的空转写不派发命令
连接失败、超时、未就绪inference_unavailable/inference_timeout,不伪装成无目标或空语音
客户端在途请求或服务队列满inference_busy
身份、尺寸、编码、Schema 不合法inference_protocol_error
帧超出配置有效期inference_result_stale,不保留无效定位结果
TTS 合成/播放失败记录反馈失败,不重跑任务

资源所有权遵循「谁创建、谁关闭」:Session 创建检测客户端并负责回收连接池与 I/O 线程;local 子进程由 Session 停止;remote 模型进程由部署者管理,Session/VoiceLoop 退出不会停止它。相应约束由 test_service_http.py、test_remote_vision.py、test_detector_config.py、test_remote.py 等回归用例看护。

依赖安装组速查

安装组用途
remoteAgent 侧 HTTP 客户端与图像编解码;不引入 Torch/FunASR/ChatTTS
camera/voice-ioAgent 侧相机、音频采集/VAD/播放
vision-serverGroundingDINO + SAM2 HTTP 服务及模型依赖
speech-server,voice-local语音 HTTP 服务 + FunASR
speech-server,chattts-server语音 HTTP 服务 + ChatTTS 合成
full/voice旧本地模型依赖的兼容入口,远程 Agent 不应安装

最后提醒三点最容易踩的边界:「无 GPU」≠「完全不装 Torch」(SO-101/LeRobot 与 OpenJiuwen 间接依赖仍在);远程失败永不回退本地模型;一次就绪成功或 stub 回归通过不能证明持续控制频率、模型质量或生产部署安全——请按上文的分链路验收清单逐项取证后再接入真实本体。

  • 具身智能
  • 人工智能
  • AI Agent
  • 机器人
  • 计算机视觉
  • Agent 编排

【免费下载链接】jiuwensymbiosis

Jiuwen Symbiosis就是一个"能懂人话、看得见物理世界、长了四肢的智能助手"。用户不需要示教,不需要教它怎么抓东西,怎么走路,就像指挥一个经验丰富的工人一样,用自然语言下任务,它就能自己完成感知、理解、规划、执行。

项目地址:https://gitcode.com/openJiuwen/jiuwensymbiosis
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询