跳转至

基于 Worker 子进程的算子物理隔离 (Node Isolation with Workers)

本篇文档是指导开发者将算子库运行在物理隔离 (Isolated) 环境下的权威实操指南:让你的算子库运行在独立的 Python 子进程中,从根源上杜绝你的依赖库版本(如 torch、transformers、diffusers、特定 CUDA 轮子)与画布中其他算子库发生版本冲突。

用户可以在编辑器的算子库设置中通过 Shared (共享/主进程) / Isolated (隔离/子进程) 下拉菜单自主切换;在底层,隔离模式的算子库均由专用的 Worker 子进程托管调度。


核心工程术语 (Vocabulary)

  • Orchestrator (主编排进程):Griptape Nodes 的核心 Python 主进程。全面掌控有向无环工作流图 (DAG)、拓扑连线、参数注册表、全局配置以及 Secrets 密钥;图形编辑器直接与编排进程保持长连接;
  • Worker subprocess (Worker 独立子进程):专用于执行特定算子库计算逻辑的独立 Python 进程。每个开启隔离模式的算子库均拥有独占的 Worker 进程,并通过 WebSocket 内部总线 (Bus) 与主编排进程双向通信;
  • process 与 aprocess:算子计算核心入口。开发者如常重写 process(self),底层会自动将其包装为协程挂载至 Worker 进程的事件循环上运行;
  • Schema probe (静态模式探测):算子库装载时的单次预检阶段。Worker 进程会预先将所有注册的算子类无参实例化一次,以向主编排进程汇报其输入输出端口参数布局。此过程发生在任何实际计算执行之前。

什么时候应该开启 Worker 物理隔离?

✅ 强烈建议开启隔离的场景: 算子库强依赖锁死特定版本的重型深度学习/多媒体包(如 torch==2.4.1、transformers、diffusers、accelerate、peft、特定编译版本的 CUDA Wheels 等),且需要与可能依赖不同版本的其他三方算子库在同一画布中共存。

❌ 建议保持在主进程 (Shared) 的场景: 算子库仅依赖轻量、高向前兼容的标准开源库(标准库、pydantic、griptape 核心包、常规 HTTP 网络请求工具等)。保留在主进程运行可免去跨进程序列化与 IPC 管道通信开销。


如何在算子库清单中声明开启隔离

在 griptape_nodes_library.json 的 metadata.declarations 中声明两个核心标签:

  1. worker_mode_compatibility:声明算子库是否在技术架构上支持 Worker 模式:
  2. COMPATIBLE:既能在主编排进程中运行,也能在 Worker 子进程中稳定运行;
  3. INCOMPATIBLE:严禁在 Worker 中运行,强制绑定主进程。
  4. suggested_worker_mode:声明未手动覆写时的出厂默认启动位置:
  5. WORKER:推荐并默认启动在独立 Worker 子进程中;
  6. ORCHESTRATOR:默认启动在主编排进程中。
{
  "name": "My Diffusion Library",
  "library_schema_version": "0.10.0",
  "metadata": {
    "author": "AI Team",
    "description": "专有生图重型算子库",
    "library_version": "0.1.0",
    "engine_version": "0.85.0",
    "declarations": [
      {
        "type": "worker_mode_compatibility",
        "compatibility": "COMPATIBLE"
      },
      {
        "type": "suggested_worker_mode",
        "mode": "WORKER"
      }
    ],
    "dependencies": {
      "pip_dependencies": [
        "torch==2.4.1",
        "transformers==4.45.2"
      ],
      "pip_install_flags": [
        "--extra-index-url",
        "https://download.pytorch.org/whl/cu121"
      ]
    }
  },
  "nodes": []
}

版本锁定原则:开启 Worker 隔离的灵魂在于锁死确定性版本(如 torch==2.4.1 而非模糊的 torch>=2.0),确保跨机器装载时绝对纯净。


跨进程物理隔离付出的工程代价 (The Trade-offs)

开启隔离意味着接受跨进程网络往返与序列化税 (Serialization Tax)。当 Worker 节点在计算中途需要读取主编排器持有的工作流状态时,必须通过内部 WebSocket 发起网络请求,这会带来微秒至毫秒级的 IPC 开销,且拉取到的数据属于“读后即刻失效的快照 (Stale-by-call)”:

  1. 通过参数传递数据,严禁在计算时反查画布连线状态:不要在 process() 内部试图查询其他节点的状态或画布宏观连线,一切必要素材必须作为标准的输入端口参数拉入;
  2. 所有跨进程操作必须通过解耦请求 (Requests) 边界流转:如需覆写全局状态,必须通过 GriptapeNodes.handle_request(SetParameterValueRequest(...)) 发起。

传递无法序列化的内存大对象 (Unserializable Values)

GPU 现存中的 Diffusion Pipeline、Latent 潜空间张量、PyTorch Model 句柄等对象根本不存在纯文本序列化形式,绝对无法作为常规参数直接通过 WebSocket 跨进程传输!

官方给出的架构级解决方案: 将产出此类大对象的输出参数标记为 Parameter(serializable=False)。引擎在底层会将该对象牢牢钉在产出它的 Worker 进程内存中,仅向跨进程总线广播一个轻量级的访问 Key (Token);下游在同一进程内接入该 Key 的算子能无感、极速恢复该原生对象——详见 非序列化数据传递指南。


开发者必须铭记的生命周期重大变化

1. __init__ 会在算子库装载时的预检阶段提前执行

Worker 进程启动时会立刻执行一次无参 Schema 预检以探测端口,因此: - 严禁在 __init__ 中执行任何物理 I/O(严禁发 HTTP 请求、严禁读写大文件、严禁校验数据库连接);超时会导致该算子直接被引擎静默注销丢弃! - 严禁在 __init__ 中触发内部事件总线请求(会引发死锁并触发 reentrant-bus-in-init 致命错误); - __init__ 必须且只能用于注册参数:self.add_parameter(...) 是该阶段唯一合法的行为。

2. 算子实例属于无状态瞬态对象 (Stateless Nodes)

每一次执行请求到达时,Worker 都会临时实例化一个全新的干净算子对象,运行完 process() 后立即彻底销毁垃圾回收! - ❌ 严禁使用 self.my_state = ... 在跨次运行之间记忆状态(下一轮运行该属性复归为空); - ✅ 跨轮次持久化数据必须托管给主编排进程:在 process() 中通过 SetParameterValueRequest 更新,下一轮运行会自动注入回 self.parameter_values。

3. 计算期间直接修改参数列表无法同步回主进程

在 process() 内部直接调用 self.add_parameter(...) 仅作用于 Worker 本地即将被销毁的临时对象,主编排器完全无法感知! 若需在运行期动态长出端口,必须派发专属请求: - AddParameterToNodeRequest - RemoveParameterFromNodeRequest


隔离就绪状态自检清单 (Isolation Checklist)

  • [ ] 在 metadata.declarations 中声明 worker_mode_compatibility: COMPATIBLE 并指定 suggested_worker_mode: WORKER;
  • [ ] 确保 __init__ 内绝对没有任何网络 I/O、磁盘读取或总线请求;
  • [ ] 严禁在 process() 中直接调用 add_parameter,必须改用 AddParameterToNodeRequest;
  • [ ] 跨节点计算数据一律通过 Parameter 端口流入,绝不在运行时盲目反查外部工作流;
  • [ ] 不依赖连线回调钩子(after_incoming_connection 等),因为 Worker 模式下连线钩子由主进程哑桩接管,子进程内不执行;
  • [ ] 强依赖的重型依赖包已锁定具体发布版本号。

严格模式 (Strict Mode) 错误侦测矩阵

本地调试启动引擎时,控制台输出带有 Worker-<id> 前缀的日志行是检验隔离健壮性的金标准:

严格模式检查规则 编排主进程表现 Worker 子进程表现 违规后果与整改指引
reentrant-bus-in-init ❌ ERROR ❌ ERROR 致命违规:在 __init__ 中调用了总线;该类直接被引擎丢弃卸载!
parameter-mutation-during-aprocess ⚠️ WARNING ❌ ERROR 致命违规:在计算体内未走请求直接原地修改参数;导致该次运算直接判定失败!
connection-hooks-inert-on-worker ⚠️ WARNING ⚠️ WARNING 告警:重写的连线生命周期钩子在 Worker 模式下处于静默未激活状态。
value-hooks-execute-only-on-worker ⚠️ WARNING ⚠️ WARNING 告警:数值变更钩子仅在 Worker 计算时执行,无法参与前端画布的实时响应。
parameter-behaviors-dropped-in-schema ⚠️ WARNING ⚠️ WARNING 提示:挂载的自定义校验器/转换器未同步给主进程,仅在 Worker 本地生效。