Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
a3bbb30
feat(inference): unify role lifecycle and routing
iArazy Sep 22, 2026
4335eab
fix(inference): publish readiness after initial async sync
iArazy Sep 22, 2026
c519b19
fix(ci): repair readiness regression test fixtures
iArazy Sep 22, 2026
9c70b3e
fix(ci): restore legacy inference test paths
iArazy Sep 22, 2026
375ed00
Merge branch 'main' into codex/rfc71-unified-inference-service
Arazyu Sep 22, 2026
fa3ca97
feat(genrm): GenRM 弹性扩缩容与 Autoscaler 接入
shanyulu Sep 25, 2026
c03940b
fix(genrm): bind drain proofs to the observed victim and fail reconci…
shanyulu Sep 25, 2026
8368ce4
fix(genrm): resubmit failed PG deletions and hot-start patched collec…
shanyulu Sep 25, 2026
4ba71eb
fix(genrm): strict int targets, fail-closed capacity, honest crash sn…
shanyulu Sep 25, 2026
196d7e3
fix(genrm): replica-invariant sampling seed for GenRM engines
shanyulu Sep 25, 2026
77beebd
fix(autoscaler): concurrent per-service evaluation and URL/status parity
shanyulu Sep 25, 2026
e7224af
fix(demos): assert training progress in each observable scaling window
shanyulu Sep 25, 2026
fddb093
fix(scripts): expandable CUDA segments for near-edge GenRM recipes
shanyulu Sep 25, 2026
8b0c6fe
fix(demos): log round-B resource samples in preregistered autoscaler run
shanyulu Sep 25, 2026
03e888f
fix(demos): match color-code-abutted rollout lines in the continuity …
shanyulu Sep 25, 2026
f6ff4c9
evidence(task4): final-head reruns — reward consistency, failure inje…
shanyulu Sep 25, 2026
af82e6a
evidence(task4): final-head training continuity r4 — three-window ass…
shanyulu Sep 25, 2026
d8466ed
fix(genrm): harden final elastic-scaling lifecycle invariants
shanyulu Sep 25, 2026
56c3343
chore(task4): slim committed evidence to final verdicts
shanyulu Sep 25, 2026
9fd03da
test(demos): adversarial sampling-divergence driver for replica-invar…
shanyulu Sep 25, 2026
c82ed85
docs(task4): bilingual demo README with the full driver inventory
shanyulu Sep 25, 2026
0a1cdb9
chore(task4): ignore raw run artifacts under committed evidence policy
shanyulu Sep 25, 2026
52036e8
fix(genrm): accept confirmed-completion reconcile for victim-less sca…
shanyulu Sep 25, 2026
194f270
fix(autoscaler): per-service evaluation loops with independent cadence
shanyulu Sep 25, 2026
48362a5
style(tests): hook-mandated docstring reflows
shanyulu Sep 25, 2026
1747eeb
fix(autoscaler): restart workers whose runtime object was rebuilt by …
shanyulu Sep 25, 2026
1dbb9e3
feat(genrm): request-level sampling seed for replica-invariant scoring
shanyulu Sep 25, 2026
945741e
fix(genrm): activate deterministic sampling so per-request seeds take…
shanyulu Sep 25, 2026
506427f
evidence(task4): seed-contract validation chain — adversarial 0/50, B…
shanyulu Sep 25, 2026
8285c76
chore(task4): move failed divergence round r1 verdict to evidence branch
shanyulu Sep 25, 2026
cafc7c1
docs(task4): pin evidence links to the frozen evidence commit 26b1c1e
shanyulu Sep 25, 2026
db99e28
fix(autoscaler): register in-flight scale ops pre-POST and hand worke…
shanyulu Sep 25, 2026
7b47d6d
docs(task4): recompute evidence pins from the committed blobs
shanyulu Sep 25, 2026
3127bad
fix(autoscaler): track the submission URL per scale operation; reject…
shanyulu Sep 26, 2026
33198f7
fix(task4): close final autoscaler control-plane ownership gaps
shanyulu Sep 26, 2026
4c13780
fix(task4): close ambiguous scale recovery lifecycle gaps
shanyulu Sep 26, 2026
16d7148
docs(task4): pin every evidence row to its exact producing commit
shanyulu Sep 26, 2026
5c1e2e7
fix(genrm): keep the radix cache under deterministic inference on pre…
shanyulu Sep 26, 2026
3127b63
docs(task4): pin final autoscaler acceptance evidence
shanyulu Sep 26, 2026
a4f55d7
test(task4): skip server-args tests when sglang_engine sees the stub …
shanyulu Sep 26, 2026
9755486
fix(autoscaler): preserve rollout terminal cleanup contract
shanyulu Sep 26, 2026
0481701
fix(genrm): respect the global attention backend when the determinist…
shanyulu Sep 26, 2026
f507d3b
test(task4): annotate the stub-guarded imports in the sampler test
shanyulu Sep 26, 2026
c8f40d7
docs(task4): index the 2026-09-27 closeout evidence (r6/r4 reconfirma…
shanyulu Sep 27, 2026
5b512d0
docs(task4): restructure EVIDENCE.md around a single current-conclusi…
shanyulu Sep 27, 2026
9095c66
docs(task4): document the GenRM scaling API contract (en/zh + OpenAPI)
shanyulu Sep 27, 2026
a55c85f
docs(rollout): document the scale-status cleanup_required contract
shanyulu Sep 27, 2026
8c422d0
docs(genrm): pin reviewed evidence index
shanyulu Sep 27, 2026
da4acbb
docs(task4): align evidence with reanalysis
shanyulu Sep 27, 2026
904b4b8
fix(inference): resolve conflicts with latest main
iArazy Oct 11, 2026
9eec00a
fix(inference): exclude placement from NPU model config
iArazy Oct 11, 2026
36ee4ba
fix(genrm): integrate elastic scaling with inference
iArazy Oct 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,27 @@ tensorboard_log
# .github
.github/copilot-instructions.md
env.sh

# task4 genrm evidence: large raw artifacts live on the evidence/task4-genrm
# branch only (see demos/task4_genrm/EVIDENCE.md); keep the working tree clean
demos/task4_genrm/results/**/load_requests.json
demos/task4_genrm/results/**/timeline.json
demos/task4_genrm/results/**/tui-*.svg
demos/task4_genrm/results/**/events.json
demos/task4_genrm/results/**/train_events.json
demos/task4_genrm/results/**/scale_history*.json
demos/task4_genrm/results/**/autoscaler.yaml
demos/task4_genrm/results/**/phase_boundaries.json
demos/task4_genrm/results/**/weight_sync_count.txt
demos/task4_genrm/results/**/driver_run*.log
demos/task4_genrm/results/**/replies.json
demos/task4_genrm/results/autoscaler_prereg_20260925_r1/
demos/task4_genrm/results/failure_injection_20260925_v1_design_flaws/
demos/task4_genrm/results/failure_injection_20260925_v2_pid_lookup/
demos/task4_genrm/results/failure_injection_20260925_v3_early_eos/
demos/task4_genrm/results/reward_consistency_20260925_v1_seed_instability/
# r2: actor first-step OOM from allocator fragmentation (fixed by expandable
# segments in the recipes); r3: continuity-tail \b regex never matched the
# color-code-abutted "rollout N:" lines (fixed in the driver)
demos/task4_genrm/results/train_continuity_20260925_r2/
demos/task4_genrm/results/train_continuity_20260925_r3_tail_regex_defect/
210 changes: 210 additions & 0 deletions demos/task4_genrm/EVIDENCE.md

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions demos/task4_genrm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Task 4 — GenRM elastic scaling demos & evidence

Contract demo, GPU E2E drivers and machine-verdict evidence for the GenRM
elastic-scaling work (PR #370 / RFC #351). Chinese mirror: [`README_zh.md`](README_zh.md).

## Contract demo (CPU, no GPU/Ray)

Run from this directory:

```bash
python -m unittest -v test_contract_demo.py
python contract_demo.py
python render_demo.py results/contract-demo.json --output results/contract-demo.html
```

Open `results/contract-demo.html` in a browser (GitHub's `blob` view shows the source; download the file or use a local checkout to run it). The page replays four deterministic scenarios: normal 1→2→1, health-check failure, backend still busy during drain, and cleanup failure followed by explicit reconciliation. Scrub the timeline to inspect route membership, admitted requests, PG ownership and the recovery boundary. The JSON is the exact event trace used by the page.

This exercises the request and lifecycle contract, including unknown-request `404`, absolute-target validation, idempotency-key replay (a keyed `NOOP` is recorded and replayed verbatim after capacity changes, never executing a new operation), `409` on key/body mismatch or unresolved cleanup, and explicit retry/reconcile paths. Engines, workers, health checks, admission, backend idleness and PGs are in-memory fakes; the `workers` field is a contract signal, not a real worker process. The demo has no Ray, SGLang, GPU, Autoscaler or real scoring. It does not establish that Task 3 supplies the required non-cancelling drain or full-worker cleanup, or that text training continues during scaling. Those remain integration and acceptance work for [RFC #351](https://github.com/redai-studio/Relax/issues/351).

## GPU E2E drivers

All drivers need a single node with free GPUs and the SGLang runtime; they deploy only Ray Serve apps they own and clean up in an outer `finally`.

- `e2e_genrm_scale.py` — manual `1→2→1` under continuous scoring: probes physical GPUs for the scale-out PG, records per-phase scores, per-engine served counts, GPU snapshots and machine verdicts.
- `e2e_autoscaler_load.py` — full autoscaler cycle under a `LOW→HIGH→STEADY→LOW'` load curve with per-service GenRM thresholds; samples capacity, decisions and history at ~1 Hz.
- `e2e_autoscaler_preregistered.py` — preregistered acceptance round: frozen thresholds and sub-assertions (A1–A8, B1–B3), a with-traffic Round A and a true-idle Round B, plus gated TUI screenshots.
- `e2e_failure_injection.py` — drain/abort/kill scenarios: deadline-abort with a fail-closed parked drain fence, SIGKILL of an in-flight victim with zero-loss retry onto the initial engine.
- `e2e_reward_consistency.py` — production dapo-genrm judge protocol over a fixed input set, attributed per engine: greedy verdicts must agree exactly; official-sampling stability is reported alongside.
- `e2e_sampling_divergence.py` — adversarial consistency: the initial engine first serves N stochastic requests alone, the elastic engine then boots with the same server seed, and the fixed probe set must still produce identical per-engine verdict sets (divergent RNG histories).
- `e2e_train_continuity.py` — sidecar monitor for the training recipe: drives `scale_out`/`scale_in` against a live DAPO+GenRM run and asserts training progress in every observable window (before / between / after), no >120 s stall, 8/8 rollouts and final capacity back to the initial engine.

Training recipes that pair with the monitor live in `scripts/training/genrm/`.

## Evidence

Machine-verdict summaries of the recorded runs live under `results/` (final verdicts and the frozen preregistration documents only); see [`EVIDENCE.md`](EVIDENCE.md) for the run-to-commit mapping, SHA256 pins, reproduction commands and known limits. Full per-request logs, event timelines, charts and failed/superseded intermediate rounds are preserved on the `evidence/task4-genrm` branch (immutable commit links from `EVIDENCE.md`).
35 changes: 35 additions & 0 deletions demos/task4_genrm/README_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Task 4 — GenRM 弹性扩缩容演示与证据

GenRM 弹性扩缩容(PR #370 / RFC #351)的契约演示、GPU E2E driver 与机器判定证据。English mirror: [`README.md`](README.md).

## 契约演示(CPU,无需 GPU/Ray)

在本目录执行:

```bash
python -m unittest -v test_contract_demo.py
python contract_demo.py
python render_demo.py results/contract-demo.json --output results/contract-demo.html
```

用浏览器打开 `results/contract-demo.html`(GitHub 的 `blob` 视图只显示源码;请下载文件或使用本地 checkout 运行)。页面回放四个确定性场景:正常 1→2→1、健康检查失败、排空期间后端仍在处理、清理失败后的显式 reconcile。拖动时间轴可查看路由成员、准入请求、PG 归属与恢复边界。JSON 是页面使用的精确事件轨迹。

演示覆盖请求与生命周期契约,包括未知请求 `404`、绝对目标校验、幂等键重放(带键 `NOOP` 会被记录并在容量变化后逐字重放,绝不执行新操作)、键/请求体不匹配或未决清理时的 `409`,以及显式 retry/reconcile 路径。引擎、worker、健康检查、准入、后端空闲与 PG 均为内存 fake;`workers` 字段是契约信号而非真实 worker 进程。演示不含 Ray、SGLang、GPU、Autoscaler 或真实打分,也不证明 Task 3 提供不可取消的排空或全量 worker 清理,更不证明扩缩期间文本训练不中断——这些属于 [RFC #351](https://github.com/redai-studio/Relax/issues/351) 的集成与验收工作。

## GPU E2E drivers

所有 driver 均需单节点空闲 GPU 与 SGLang 运行时;只部署自己拥有的 Ray Serve 应用,并在外层 `finally` 中清理。

- `e2e_genrm_scale.py` —— 持续打分下的手动 `1→2→1`:为扩容 PG 探测物理 GPU,记录各阶段得分、每引擎服务计数、GPU 快照与机器判定。
- `e2e_autoscaler_load.py` —— `LOW→HIGH→STEADY→LOW'` 负载曲线下的 Autoscaler 全周期(按服务 GenRM 阈值);以 ~1 Hz 采样容量、决策与历史。
- `e2e_autoscaler_preregistered.py` —— 预注册验收轮:冻结阈值与子断言(A1–A8、B1–B3),带流量的 Round A 与真实空闲的 Round B,外加门控 TUI 截图。
- `e2e_failure_injection.py` —— 排空/中止/强杀场景:deadline-abort 触发 fail-closed 停泊排空栅栏,SIGKILL 在飞 victim 后全部请求零丢失重试到初始引擎。
- `e2e_reward_consistency.py` —— 生产 dapo-genrm judge 协议跑固定输入集并按引擎归属:greedy 判定必须逐输入一致;官方采样稳定性一并上报。
- `e2e_sampling_divergence.py` —— 对抗一致性:初始引擎先独跑 N 个随机请求,弹性引擎再以相同 server 种子启动,固定探针集仍须产出一致的逐引擎判定(发散的 RNG 历史)。
- `e2e_train_continuity.py` —— 训练配方的 sidecar 监控:对运行中的 DAPO+GenRM 训练驱动 `scale_out`/`scale_in`,并断言每个可观测窗口(前/之间/后)内训练进度、无 >120 s 停滞、8/8 rollouts 与终容量回到初始引擎。

与监控器配套的训练配方位于 `scripts/training/genrm/`。

## 证据

已记录运行的机器判定摘要位于 `results/`(仅最终 verdict 与冻结的预注册文档);run→commit 映射、SHA256 pin、复现命令与已知限制见 [`EVIDENCE.md`](EVIDENCE.md)。完整的逐请求日志、事件时间线、图表与失败/被取代的中间轮保留在 `evidence/task4-genrm` 分支(`EVIDENCE.md` 内为不可变 commit 链接)。
Loading
Loading