Skip to content

feat(compilation): freeze FL dispatch before torch.compile; route hot ops via flag_gems.pt2 (vLLM 0.24) - #448

Open
JiaryCoder wants to merge 2 commits into
flagos-ai:mainfrom
JiaryCoder:dispatch-freeze-torch-compile
Open

JiaryCoder wants to merge 2 commits into
flagos-ai:mainfrom
JiaryCoder:dispatch-freeze-torch-compile

Conversation

@JiaryCoder

Copy link
Copy Markdown

PR Category

Core

PR Type

New Features

Description

使 FL dispatch 层与 FlagGems 后端在 vLLM 0.24 的 torch.compile(custom_ops=all
fullgraph AOT)下可用。在此之前,vllm serve --compilation-config '{"custom_ops": ["all"]}'
会在 profile_run 的第一个 RMSNorm 处失败(EngineCore failed to start)。

两个机制,与内部 0.20.2 交付件同设计:

  1. Dispatch 冻结 —— freeze_dispatch() 在首次 Dynamo trace 前一次性解析所有
    CachedOp;冻结后的调用只是 impl.fn(*args),图中不再出现 manager/policy/锁/
    IO dump/异常回退。FrozenDispatchManifest 记录策略指纹与逐算子选择
    (impl_id/kind/vendor/callable),其 sha256 写入
    VllmConfig.additional_config["vllm_fl_dispatch_fingerprint"],不同的后端选择
    产生不同的 vLLM 编译缓存 key。冻结期间拒绝 policy 变更;reset_default_manager()
    触发解冻;fork 出的子进程重置冻结状态。
  2. PT2 路由 —— NVIDIA 上 FlagGems 实现把 RMSNorm / fused-add RMSNorm /
    SiLU-GELU-and-mul / in-place RoPE / MoE 基础算子路由到 flag_gems.pt2.*
    triton_op + wrap_triton 包原始 kernel 对象)。eager 数值不变(torch.equal)。

依赖:FlagGems 侧 PR(flag_gems.pt2),见 flagos-ai/FlagGems 的 add-pt2-support 分支。

Related Issues

Fixes #298

Changes

  • vllm_fl/dispatch/__init__.pyFrozenOpSelectionFrozenDispatchManifest
    freeze_dispatchthaw_dispatchis_dispatch_frozenget_frozen_dispatch_manifest
    CachedOp._frozen_impl 快路径、os.register_at_fork 重置。
  • vllm_fl/dispatch/policy.pyvllm_fl/dispatch/manager.py_ensure_dispatch_mutable
    守卫;reset 时解冻。
  • vllm_fl/compilation/dispatch.py(新增):freeze_dispatch_for_compile(vllm_config)——
    冻结、指纹写入 additional_config、为 logging.Logger.{debug,info,warning,error}
    注册 ignore_logging_functions
  • vllm_fl/worker/model_runner.pyload_model() 中、compile 路径之前调用。
  • vllm_fl/dispatch/backends/flaggems/impl/{normalization,activation,rotary,fused_moe}.py
    flag_gems.vendor_name == "nvidia"(RMSNorm 另加 not use_c_extension)路由到 pt2。

Testing

NVIDIA(CUDA_VISIBLE_DEVICES=0,1),vllm 0.24.0,torch 2.11.0+cu130,triton 3.6.0,
FlagGems 为配套 PR 版本。

  • vllm serve /data/models/MiniCPM5-1B --tensor-parallel-size 2 --compilation-config '{"custom_ops": ["all"]}'USE_FLAGGEMS=1 VLLM_PLUGINS=fl
    此前 EngineCore failed to start;现编译 14.2 s,51/51 PIECEWISE + 51/51 FULL
    CUDA graph,chat 请求正常返回。
  • Qwen3.5-0.8B 清缓存冷编译:输出正确、logprobs 有限。
  • Qwen3.6-35B-A3B(MoE,TP=2)eager vs compile tie-aware cross-phase:16/16 位置逐位一致。
  • 7 个算子 eager/compile parity:max|diff| = 0.0。
  • vllm 本体零改动(4404/4404 RECORD 哈希一致)。

Checklist

  • I have run the existing tests and they pass(CI 会跑 tests/run.py;本地验证见上)
  • I have added tests for my changes(本 PR 未加;冻结行为已按上述验证,可按需补
    tests/unit_tests/dispatch/test_freeze.py
  • I have updated the documentation(如适用)

…hot ops through FlagGems PT2 contracts (vLLM 0.24)

With `--compilation-config '{"custom_ops": ["all"]}'` vLLM 0.24 traces
`CustomOp.forward_oot` fullgraph. The FL dispatch control plane (manager
lookup, policy epochs, RLock, IO dump, exception-driven fallback) and the raw
FlagGems launchers (LibEntry, logger.debug) are not Dynamo-traceable, so
profile_run aborted at the first RMSNorm (Unsupported method call
`__getitem__` in LibEntry.run; NameError('ext') in the Inductor subprocess).

* dispatch/__init__.py: `freeze_dispatch()` resolves every `CachedOp` once
  before the first trace; frozen calls are a plain `impl.fn(*args)`.
  `FrozenDispatchManifest` (+ `FrozenOpSelection`) records policy fingerprint
  and per-op impl_id/kind/vendor/callable; sha256 of that is the manifest
  fingerprint. `thaw_dispatch()`, `is_dispatch_frozen()`,
  `get_frozen_dispatch_manifest()`. Post-fork reset via `os.register_at_fork`.
* dispatch/policy.py, dispatch/manager.py: reject policy mutation while
  frozen; `reset_default_manager()` thaws.
* compilation/dispatch.py: `freeze_dispatch_for_compile(vllm_config)` — binds
  the manifest fingerprint into `additional_config` (=> vLLM compile-cache
  identity) and registers `logging.Logger.{debug,info,warning,error}` in
  `torch._dynamo.config.ignore_logging_functions`.
* worker/model_runner.py: call it in `load_model()` before any compile path.
* backends/flaggems/impl/{normalization,activation,rotary,fused_moe}.py: on
  NVIDIA route to `flag_gems.pt2.*` (same kernel objects; eager unchanged).

Verified on NVIDIA, TP=2, custom_ops=all: MiniCPM5-1B serve (14.2 s compile,
51/51 PIECEWISE + 51/51 FULL CUDA graphs), Qwen3.5-0.8B cold compile,
Qwen3.6-35B-A3B MoE eager/compile tie-aware cross-phase 16/16 exact.
Requires the matching FlagGems PR (flag_gems.pt2).

Signed-off-by: JiaryCoder <jiary.zhang@icloud.com>
… ops directly

Register the FlagGems implementations of the nine common ops (silu_and_mul,
gelu_and_mul, rms_norm, rotary_embedding, moe_align_block_size, moe_sum,
topk_softmax, invoke_fused_moe_triton_kernel, grouped_topk) by importing the
impl functions inside register_builtins() and binding them directly, instead
of binding FlagGemsBackend bound methods that import lazily on first call.

With lazy binding, the impl modules -- and with them the flag_gems.pt2
triton_op registrations and the pointwise plan materialisation done at
impl.activation import -- were only executed when Dynamo first inlined the
backend method, i.e. inside the traced region. Doing that work during
backend registration keeps torch.library registration and codegen out of
the compiled graph, so freeze_dispatch() resolves every CachedOp to the
final function object and the first trace imports nothing.

Verified in a fresh process (no warm-up): after registration all impl
modules, flag_gems.pt2.* and 24 pointwise plans are present and the six
flag_gems_pt2 ops are registered; freeze imports nothing; the first-ever
call of each op inside a fullgraph trace compiles and equals eager. In a
real engine the freeze-time module state is impl=7 pt2=8 plans=24 ops=6/6.

Signed-off-by: JiaryCoder <jiary.zhang@icloud.com>
@JiaryCoder
JiaryCoder requested review from ceci3, cyber-pioneer and physics31415926 and removed request for ceci3 and physics31415926 September 8, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RotaryEmbedding fails during torch.compile graph capture with vllm-plugin-FL

1 participant