服务与环境
服务是 skill 或模型角色调用的模型进程:用于分割的 SAM 3、用于指点的 Molmo2、VLM、VLA、OpenWAM、运动学。环境是任务运行的地方:本机上某个 benchmark 的官方环境,或 The Simulator 中的一个任务。两者都在某次运行第一次需要时才安装,此前从不安装;在 GPU 上的放置从不改变一次运行计算的内容,只改变在哪里、何时计算。
每个服务一个文件,services/<name>.toml:如何启动它、它的端口和显存、它运行所在的环境,以及它的权重从哪里来。
kind = "segmenter"summary = "SAM 3 instance segmentation from text or point prompts"protocol = "http"command = ["{python}", "-u", "services/servers/serve_sam3.py", "--checkpoint", "{weights}/sam3/sam3.pt", "--port", "{port}"]port = 8810vram_gb = 7.2load_seconds = 60client = { url = "{url}" }
# The environment the service runs in, built the first time a run needs it.[environment]python = "3.11"requirements = ["torch==2.7.0", "timm==1.0.30", "ftfy==6.1.1", "iopath==0.1.10", "pycocotools==2.0.11"]sources = [{ repo = "https://github.com/facebookresearch/sam3", rev = "<pinned commit>", install = "editable" }]
[[weights]]dir = "sam3"modelscope_model = "facebook/sam3"{python} 是该服务自身环境的解释器,因此依赖相互冲突的服务(一个需要 Python 3.10 的策略,另一个基于 JAX)各自拥有自己的环境。学习型策略不需要我们的任何服务端代码:协议 xpolicylab 指明 XPolicyLab 的策略目录、checkpoint 和覆盖项,由 XPolicyLab 自己的 setup_policy_server.py 提供服务。XPolicyLab 的任何策略只需一个清单就能成为学习型 skill(添加 VLA)。各服务及其实测显存见服务参考;清单的键见配置参考。
首次使用时安装
Section titled “首次使用时安装”一次运行开始时,agent 的配置决定启用哪些 skill,每个 skill 写明它需要的服务种类。对于本次运行将要调用而本机尚未具备的每个服务,harness 按其清单的描述构建环境,安装固定版本的依赖和源码,下载并校验权重,然后启动它。所有内容都放在 ~/.cache/harness(HARNESS_HOME)下,因此下一次运行立即开始。服务在配置中被关闭的 skill 从不安装;它退出本次运行,prompt 也随之去掉它的文本。
benchmark 也是同样的方式:在 RoboDojo 上的第一次运行会安装其官方环境(模拟器、其资产和观测契约),而在 The Simulator 的任务上运行只需要 The Simulator 的客户端。
放置与 deploy 文件
Section titled “放置与 deploy 文件”没有 deploy 文件时,harness 把它启动的东西放到它找到的 GPU 上:全部放得下时常驻,否则按需,一次一个模型地共享一块 GPU。deploy 文件 configs/deploy/<machine>.toml 则由你来选择:项目可以使用的 GPU、权重存放的位置、模拟器 worker,以及每个服务如何运行。一个 deploy 文件描述一台机器,因此它不属于项目:git 忽略 configs/deploy/ 中除下面的 example-*.toml 以外的所有文件,放在其他位置的文件可以通过 --deploy PATH 或 $HARNESS_DEPLOY 使用。
| 模式 | 含义 |
|---|---|
resident |
在第一个 episode 之前(或由 harness up)启动,保持运行 |
on_demand |
在 skill 第一次调用它时由 broker 启动;在 idle_seconds 之后,或其 swap group 中的另一个成员被需要时停止 |
external |
由别人运行,在本机或另一台机器上;只有一个 url,不安装任何东西 |
off |
不在这里 |
gpu = "auto" 把服务放到对其 vram_gb 来说空间最大的 GPU 上,从最大的服务开始;一个 swap group 的成员放到同一块 GPU 上,所需空间等于其中最大的那个。
# A machine with four 24 GB GPUs: the agent's models resident on GPU 0 (SAM 3 and# Simate), Molmo2 and OpenWAM on demand in one swap group on GPU 1 for experiments that# turn them on (a pointer role, `--set 'agent.services.world_models=["openwam"]'`), and# the simulator workers on the other two, two per GPU.# Copy to configs/deploy/<your machine>.toml (git-ignored) and set the paths and GPUs.weights = "~/harness-weights"state = "~/.cache/harness-policy/services"gpus = [0, 1, 2, 3]gpu_memory_gb = 24
# Simulator workers of `harness run`: two RoboDojo workers per GPU (6-9 GB each).[sim]gpus = [2, 3]workers_per_gpu = 2base_port = 8771
[services.sam3]gpu = 0
[services.simate]gpu = 0
[services.molmo2]gpu = 1mode = "on_demand"swap = "experiments"
[services.openwam]gpu = 1mode = "on_demand"swap = "experiments"# A machine with two 24 GB GPUs: the agent's models stay resident on GPU 1 (SAM 3 7.2 GB# and Simate 14 GB; started once with `harness up`), the simulator workers run on GPU 0.# Copy to configs/deploy/<your machine>.toml (git-ignored) and set the paths.weights = "~/harness-weights"state = "~/.cache/harness-policy/services"gpus = [0, 1]gpu_memory_gb = 24
[sim]gpus = [0]workers_per_gpu = 2
[services.sam3]gpu = 1
[services.simate]gpu = 1# A machine with one 24 GB GPU. The simulator (6-9 GB) leaves room for one model at a# time: SAM 3 (7.2 GB) and Simate (14 GB) are on demand in one swap group, so the broker# loads the one a skill calls and swaps when the other is needed. The simulator waits# while a model loads, so this costs wall time, not episode steps, and the identity is# that of a machine where both stay resident. One thing differs: Simate keeps a memory of# past frames, and swapped out it starts that memory afresh, so a policy run after a SAM 3# call in the same episode does not see the frames before it (docs/src/content/docs/guides/small-machine.md).# Copy to configs/deploy/<your machine>.toml and set the paths.weights = "~/harness-weights"state = "~/.cache/harness-policy/services"gpus = [0]gpu_memory_gb = 24
[sim]gpus = [0]workers_per_gpu = 1
[services.sam3]gpu = 0mode = "on_demand"swap = "models"
[services.simate]gpu = 0mode = "on_demand"swap = "models"# No GPU for models: only the simulator runs here, every model is hosted (the main and# vlm roles). Without a segmenter, segmentation and the tools built on it (locate, pick,# release, ...) drop out of runs on this machine, and without a policy server the# learned skills: a smaller configuration with another identity.weights = "~/harness-weights"gpus = [0]
[sim]gpus = [0]workers_per_gpu = 1按需与 swap group
Section titled “按需与 swap group”在不能每个模型一块 GPU 的机器上,模型共享 GPU。按需服务在某个客户端第一次请求它时启动:每个客户端(策略和世界模型的客户端、分割器、由服务支撑的对话角色)在每次调用之前询问 broker,broker 启动该服务并等待它响应。同一个 swap 组的服务共享一块 GPU,一次只加载一个;当组内另一个成员正在使用时 broker 等待,然后换入。
模型加载期间模拟器不前进(skill 的调用只是耗时更长),因此换入换出的代价是墙钟时间,而不是 episode 步数:本次运行计算的内容与所有模型都常驻时相同,只有一点例外:带记忆的策略(scoped = true,例如 Simate)被换出后,其记忆会重新开始。
一次运行会自行安装和启动它需要的东西;这些命令用于手动完成。
harness services # the manifestsharness doctor # what is installed, what an agent would still install, GPUs and free memoryharness install sam3 simate # install ahead of time: environments, sources, weightsharness up # start the resident services (and the broker)harness statusharness down # stop what harness up started当某个服务的端口已经有响应时(手动启动的,或由另一个 checkout 启动的),harness up 不去动它;harness down 只停止它自己启动的东西,通过逐级升级的信号(SIGINT 或 SIGTERM,然后 SIGKILL)。日志和 pid 文件写到 deploy 文件的 state 目录。详情见管理服务。
自动生成的 deploy 文件
Section titled “自动生成的 deploy 文件”导出的 XPolicyLab 策略在启动时为其策略服务器可见的 GPU 写出自己的 deploy 文件:每个服务使用自己的端口(几个实例可以共享一台机器),放得下空闲显存时常驻,否则策略和世界模型在一个 swap group 中按需加载,再不行则除运动学以外的所有模型都按需加载。agent 的模型(运动学、SAM 3、Simate:23.2 GB)可以常驻在一块 24 GB 的 GPU 上(通过 XPolicyLab 评测)。