Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
39cca2d
docs(metainfer): 更新 star-history 图表 + 新增学术研究与贡献章节
myrfy001 Jul 15, 2026
1da9d36
fix(gen-infer-framework): E_perf_test 诊断捕获 + planner 上下文增强 + implemen…
myrfy001 Jul 15, 2026
9312a61
feat(metainfer): 新增 find-low-hanging-kernel task 插件
myrfy001 Jul 15, 2026
eb03433
fix(server): launcher.status 优先认 orchestrator.pid::finished_at + 进程状态…
myrfy001 Jul 15, 2026
e477cf8
fix(metainfer): SSOT 专项整治 — 统一 req 字段读取 + 消除重复逻辑 + 修复数据竞态
myrfy001 Jul 15, 2026
9da1be3
feat(metainfer): 新增 port-model task 插件
myrfy001 Jul 17, 2026
2225648
docs(metainfer): 英文 README 同步中文版——Quick Start 新增 ccb 安装步骤
myrfy001 Jul 17, 2026
57765d1
docs(metainfer): 中文 README 同步英文版 Quick Start 新增 ccb 安装步骤
myrfy001 Jul 18, 2026
2822169
feat(gen-cpp): add continuous batching contracts
FY-26 Jul 21, 2026
8e21bcd
feat(evolve-kernel): 新增 GPU 内核演化优化任务,含 8-phase 流水线
6eanut Jul 21, 2026
a299687
feat: add standalone C++ inference framework task
codex Jul 15, 2026
a7d7a12
docs: replace Python contracts with native C++ contracts
codex Jul 16, 2026
ce15ba2
feat(cpp-card): harden native framework generation workflow
wxr123-wxr Jul 17, 2026
3fd0cc6
feat(calc_value): 新增 /control 端点支持单独重跑任意 step
myrfy001 Jul 21, 2026
7396ba9
feat(port-model): 完整实现 6-agent 流水线 + Form Widget Registry + 关键 bug 修复
myrfy001 Jul 22, 2026
2ee4301
feat(cluster): add NFS-safe primitives, worker registry, and cluster …
myrfy001 Jul 22, 2026
5f0f2c4
feat(cluster): add GPU-level scoreboard with all-or-nothing acquisition
myrfy001 Jul 22, 2026
a249037
feat(cluster): add file-system message queue (submit/consume/result)
myrfy001 Jul 22, 2026
6c0f076
feat(worker): add worker daemon, job runner, and FakeWorker test harness
myrfy001 Jul 22, 2026
30e8064
feat(cluster): add Python SDK + metainfer-cluster CLI
myrfy001 Jul 23, 2026
778a567
feat(cluster): add admin endpoints + Cluster Overview / Job Detail fr…
myrfy001 Jul 23, 2026
f37f545
feat(cluster-tasks): wire worker_nodes form field + remote perf path …
myrfy001 Jul 23, 2026
9873dd9
feat(port-model): pass worker_nodes into P5/P6 prompts for distribute…
myrfy001 Jul 23, 2026
567a8a2
feat(cluster-tasks): emit worker_failure timeline event on remote per…
myrfy001 Jul 23, 2026
f0bd91d
test(cluster-tasks): add H.5 integration tests for remote perf + PP2 …
myrfy001 Jul 23, 2026
1bbe45a
feat(cluster-e2e): add 5 cross-module E2E tests + force-release cance…
myrfy001 Jul 23, 2026
c1794bc
docs(cluster): add multi-node architecture + agent SDK guide; CLAUDE.…
myrfy001 Jul 23, 2026
670c77d
docs(readme): add multi-node worker setup instructions
myrfy001 Jul 23, 2026
c6f1933
feat(port-model): rework P6 with iterative port-test loop + launch_co…
myrfy001 Jul 23, 2026
e92716f
fix(port-model): scope rerun_step memory wipe to ≤ step index
myrfy001 Jul 23, 2026
ebbb5cc
fix(port-model): escape row-layout literal in P6 prompt f-string
myrfy001 Jul 23, 2026
91d8fea
fix(cluster): list_claims returns all GPUs including free ones
myrfy001 Jul 23, 2026
242317d
fix(launcher): record hostname in pid file to fix multi-node liveness
myrfy001 Jul 23, 2026
432fb2a
feat(cluster, port-model): generalize multi-node launch, mandate clus…
myrfy001 Jul 23, 2026
44c473e
feat(port-model): forbid single-node fallback when worker_nodes set
myrfy001 Jul 23, 2026
d050241
fix(cluster): reject worker re-registration when hostname changes
myrfy001 Jul 24, 2026
578cc37
feat(webui): show each agent's latest output in the live agents panel
myrfy001 Jul 24, 2026
33e376a
fix(launcher): pin METAINFER_ROOT into orchestrator + sub-agent env
myrfy001 Jul 24, 2026
6173904
fix(bootstrap): stamp kernel starttime in orchestrator.pid, not time.…
myrfy001 Jul 24, 2026
69c87b9
ui(agents-panel): cap tail at 10 events; align bg with dark theme
myrfy001 Jul 24, 2026
8791d8f
feat: add independent GEMM kernel optimization task
FY-26 Jul 21, 2026
bf6a682
feat(opt-gemm): improve GEMM optimization workflow
FY-26 Jul 24, 2026
09dfaaa
feat(gen-cpp): harden framework generation pipeline
wxr123-wxr Jul 23, 2026
dc40eb1
feat(opt-gemm): stabilize hipprof champion evaluation
Aug 24, 2026
74f32d5
feat(sglang-trace-analyze): scaffold new task plugin for SGLang torch…
Aug 4, 2026
87b88c7
fix(sglang-trace-analyze): wire analysis modules and complete kernel_…
Aug 5, 2026
545ae13
fix(sglang-trace-analyze): add DeepSeek V4 parser flags to run_benchmark
Aug 5, 2026
e5a7de3
fix(sglang-trace-analyze): make pipeline resilient to BENCHMARK failure
Aug 5, 2026
90ec174
fix(sglang-trace-analyze): correct build_dir_name to reflect CUDA Gra…
Aug 5, 2026
61fb41f
fix(sglang-trace-analyze): classify cross_device_reduce as Reduce
Aug 5, 2026
a1b435b
fix(sglang-trace-analyze): embed K100 env vars into run_benchmark.py
Aug 5, 2026
46d93d5
feat(sglang-trace-analyze): redesign frontend with dashboard, donut c…
Aug 5, 2026
e81ae6a
fix(sglang-trace-analyze): improve mapping confidence with kernel nam…
Aug 5, 2026
e5bc230
feat(sglang-trace-analyze): add TFLOPS, bandwidth, structure mapping,…
Aug 5, 2026
6fa5b71
fix(sglang-trace-analyze): prefer formal traces, detect CUDA Graph fr…
Aug 5, 2026
4f8df65
feat(sglang-trace-analyze): add MFU distribution histogram and freque…
Aug 5, 2026
33922c6
fix(sglang-trace-analyze): enrich formal traces with TFLOPS from mapp…
Aug 5, 2026
0fa0b31
feat(sglang-trace-analyze): add autogenerated Key Findings panel
Aug 5, 2026
1580545
feat(sglang-trace-analyze): rule-based hints + executive summary banner
Aug 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
86 changes: 86 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,69 @@
- 文件系统即数据库;server 与 orchestrator 解耦,通过文件系统传递状态
- 多节点通过共享文件系统协同,每个节点只写自己的 `nodes/<node_id>/`

## 数据一致性:单一数据源(Single Source of Truth)

**文件系统即数据库**这一选择的代价是:失去数据库内置的一致性约束。任何"同一份事实"被存到多个文件,都会在并发/重启/部分写入下漂移,最终表现为难以排查的功能 bug。下列原则**强制执行**:

### 原则

1. **每份事实有且只有一个权威文件**(source of truth)。其他文件需要这份信息时,要么从权威源读取后派生(运行时计算),要么显式声明为"不可回读的历史快照"(写完只用于展示/审计,不再驱动逻辑)。
2. **严禁双向同步**。如果 A 是权威、B 是缓存,B 只能由 A 单向派生;绝不存在"B 改了回写 A"或"A、B 互相更新"的路径。
3. **冷重启路径必须重新走权威源**。任何在内存/进程里持有的状态(limit、pid、status)一旦进程退出就丢失;重启时只能从权威文件读,不能从 requirements.json / form 副本读"为了方便"。
4. **新增字段时先问"谁是权威"**。不要图省事把值复制到第二个文件——短期的省事会变成长期的 bug 工厂。
5. **历史快照必须标注**。某文件如果只是建任务时的表单记录(之后不再驱动运行时),必须在 schema 注释里写明:"historical record, runtime reads from <other_file>"。

### 已确立的权威源(参考)

| 数据 | 权威源 | 历史快照 / 派生 |
|---|---|---|
| 预算阈值 | `token_budget.json::config.max_cost_usd` | `requirements.json::token_budget_max_cost_usd`(建任务时表单值,运行时不再读) |
| 预算累计 | `token_budget.json::totals` | `timeline.jsonl` 的 `token_usage` 事件(展示用,从权威派生) |
| 运行时状态 | `run.json`(phase / iteration / **finished / final_status**) | `registry.json`(**仅身份**:id/type/label/state_dir/workspace_dir/created_at/launcher。**绝不**缓存进程状态) |
| 任务规格 | `requirements.json`(task_type / form / label / created_at) | `registry.json::type/label`(缓存);run.json 不再存 task_type |
| 进程存活 | OS 进程表(`/proc/<pid>`)+ `orchestrator.pid`(pid / started_at / finished_at / exit_hint) | `runtime.json::tasks.<id>`(仅 WebUI session 用 boot_id 标记归属,不作为状态查询源);**registry.json 不存进程状态** |
| 进程死亡清理 | `launcher._reap_dead_pid_file()`(单一 reap 路径) | reconcile / liveness / kill 都**调它**,禁止另写 `_write_pid_file_finished` 这种只更新部分文件的简化版 |
| Worker 身份 + GPU 拓扑 | `cluster/workers/<node_id>.json` | WebUI `/api/cluster/workers` 响应(运行时派生,**不缓存到任何其他文件**) |
| Worker 心跳 | `cluster/workers/<node_id>.heartbeat` 的 mtime | `.alive` 派生量(`is_stale_heartbeat()` 读取);**永不重写 JSON 来更新心跳** |
| GPU slot 持有者 | `cluster/scoreboard/<n>/gpu-<i>.claim`(link 后不可变) | `.meta.json`(lease_until 可改;renew_lease 写这里) |
| 远程 Job spec | `cluster/inbox/<worker>/<job_id>/job.json` | WebUI `/api/cluster/jobs` 响应(派生) |
| 远程 Job 结果 | `cluster/replies/<orch>/<job_id>.result.json` | timeline.jsonl 的 `worker_failure` 事件(派生,展示用) |
| 远程 Job 日志 | `cluster/inbox/<worker>/<job_id>/{stdout,stderr}.log` | 唯一权威,无派生 |
| Slot 强制释放 | `scoreboard.force_release()`(**单一 reap 路径**,与 cluster reaper 共享) | WebUI `/api/cluster/scoreboard/force-release` 调它;mqueue `reap_orphaned_submissions` 调它;scoreboard `reap_expired_claims` 调它。**禁止另写简化版 reaper** |

### 已知反模式(**禁止**)

- **双写**:同一字段被两个文件各持一份,且都被运行时读取 → 必然漂移。
- 已修复的例子:`requirements.json::token_budget_max_cost_usd` 和 `token_budget.json::config.max_cost_usd` 曾经都被读,导致 WebUI 调整预算后冷重启失效(commit 待补)。
- 已修复的例子:`task_type` 曾经同时存在 requirements.json / run.json / registry.json,已从 run.json 移除(orchestrator 加载时 load_run 过滤未知字段,兼容旧文件)。
- 已修复的例子:`created_at` 曾经同时存在 registry.json / run.json,已从 run.json 移除(registry.json::created_at 是唯一权威源)。
- 已修复的例子:进程状态 (pid / started_at / finished_at) 曾经**三处存储** —— `orchestrator.pid` / `runtime.json::tasks.<id>` / `registry.json::tasks[]`。registry 那份名义上是"派生缓存",实际**没有任何派生函数**,reconcile / _reap_dead_pid_file / kill 各自选择性同步;`tasks.update_task` 里 `if v is None: continue` 还静默吞掉了 `pid=None` 的清除语义,导致死任务的 registry 永远显示 stale pid,liveness 用它做 pre-filter 时直接走错路。已**从 registry 移除 pid/started_at/finished_at 字段**,所有进程状态查询只走 `launcher.status()` 读 `orchestrator.pid`;旧 registry.json 通过 `_strip_legacy` 兼容。
- **多条 reap 路径效果不一致**:reconcile 原来用自己的 `_write_pid_file_finished`(只碰 orchestrator.pid),而 liveness 用 `launcher._reap_dead_pid_file`(还会刷 run.json + 写 timeline)。两条路径 → 同样的死亡事件,UI 拿到的信号不一致。**任何"清理死亡任务"的代码都必须调 `launcher._reap_dead_pid_file`**,禁止另写简化版。
- **构造函数参数压过文件**:构造函数从 A 文件读值传入,`_load()` 看到"非 None"就跳过 B 文件——这等价于把 A 钉死为权威。正确做法是构造函数只传"env override",文件值由 `_load()` 单独决定。
- **多 task 包复制同一份解析逻辑**:每个 task orchestrator 自己实现一遍 cascade → 修一个 bug 要改 N 处。共享逻辑下沉到 `metainfer/orchestrator/` 公共层。
- **字段别名 + 多 reader 各写一份 fallback 链**:例如 requirements.json 曾经既支持扁平 `target_model` 又支持嵌套 `answers.target_model` / `form.target_model`,每个 reader 自己写 `req.get("x") or (req.get("answers") or {}).get("x")` —— 12+ 处复制,每处 null 处理略有不同。已加 `metainfer.orchestrator.requirements.req_field()` 统一读取,所有 task 包的读取都应走这个 helper。
- **跨主机 flock**:NFS 上 `fcntl.flock` 语义不可靠,多个主机可能同时拿到同一把锁。cluster 模块**必须**用 `os.link`-based claim(`fs_primitives.link_claim`),禁止用 flock 跨节点互斥。
- **写第二个 reaper**:cluster 已有 `scoreboard.force_release` 作为**单一 reap 路径**(镜像 `launcher._reap_dead_pid_file` 不变量)。WebUI force-kill / mqueue `reap_orphaned_submissions` / scoreboard `reap_expired_claims` 全部**必须**调它。禁止写只 unlink claim 文件不写 cancel.marker、或不调 `force_release` 的简化版"清理函数"。
- **重写 heartbeat JSON**:worker 心跳只通过 `touch_heartbeat()` 更新 `cluster/workers/<id>.heartbeat` 文件的 **mtime**。重写 `workers/<id>.json` 来"更新心跳"会破坏 SSOT(JSON 是身份+拓扑的权威源,应在 cold start 时一次性写)。
- **claim 文件 link 后改动**:`gpu-<i>.claim` 通过 `os.link` 创建后**不可变**。续约写到 sibling `.meta.json`(flock 内 atomic rewrite),reaper 优先读 meta.json 的 lease_until。直接 unlink+relink claim 来"续约"会丢失 secret 校验,破坏租约安全。
- **Worker 持有 LeaseToken**:租约属 orchestrator(它在 `RemoteJob.__exit__` 里 release)。worker 只负责跑 job + 写 result,**永远不**调用 `release_gpus`。否则 worker 进程崩溃时 slot 不会被 orchestrator 的 finally 释放。

### requirements.json 扁平化规约

WebUI 的 `create_task` 把表单 answers **扁平展开**到顶层(`{"task_id":..., "target_model":..., "max_iterations":"50", ...}`),没有 `answers` 或 `form` 子键。

- **写**:只写扁平。新代码不要在 requirements.json 里塞 `answers` / `form` 子字典。
- **读**:用 `metainfer.orchestrator.requirements.req_field(req, key)` / `req_field_int` / `req_field_float`。helper 内部保留对历史嵌套形式的兼容(旧文件、test fixture),但 production 路径只走扁平。
- **新加字段**:在 task 的 `form.yaml` 里声明 → WebUI 自动写入扁平顶层 → reader 用 `req_field` 读。不需要改 requirements.json 的 schema 文档。

### Code review 检查清单

提交前自问:
- [ ] 我新增/修改的字段,是否已经有别的文件存了?如果是,谁是权威?
- [ ] 我的代码读这个字段时,读的是权威源,还是某个缓存?
- [ ] 冷重启后,我的逻辑还能拿到正确值吗?(写一个测试覆盖 restart 场景)
- [ ] 我有没有把"派生量"当"权威量"写到磁盘?(派生量应每次计算,不持久化)

## 运行时目录结构

每个 task 占用 **两个并列子树**,挂在 `$METAINFER_ROOT/nodes/<node_id>/` 下:
Expand Down Expand Up @@ -70,6 +133,29 @@ $METAINFER_ROOT/ (默认 <cwd>)
- task plugin → `/api/{type}/{task_id}`
- 前端静态资源 → `/static/plugins/{type}/`

### Form Widget Registry

新建任务类型时如果需要 form.yaml 内建 widget(text/textarea/number/select/multiselect/radio/file)以外的输入控件,**不要改 sys_shell**。改用自己的 widget:

1. 把 widget 组件写到 `tasks/<your_task>/static/components/<name>.js`,导出一个 Preact 组件,props 至少支持 `{ field, value, onChange, onInput, error }`(你的组件按需 destructure)。
2. 写一个 `tasks/<your_task>/static/form-overrides.js`,在其中调用:
```js
import { registerFormWidget } from "app/form-registry";
import { MyWidget } from "./components/my-widget.js";
registerFormWidget("my-widget", MyWidget);
```
3. 在 `WebPlugin.importmap_entries` 里登记一个 `app/form-overrides/<type>` 键指向该文件:
```python
_IMPORTMAP_ENTRIES = {
"app/form-overrides/<your-task-type>": f"{_STATIC_PREFIX}/form-overrides.js?v=CACHE_BUST",
}
```
4. 在 `form.yaml` 里通过 `override_component: my-widget` 引用。

加载顺序:`main.js` 先 eagerly import `app/form-builtin-registrations`(注册并 lock 内建 widget),再 `await loadAllPluginOverrides()` 扫描 importmap 里所有 `app/form-overrides/*` 键动态 import。Last-wins:同名 widget 后注册者覆盖先注册者。被 lock 的内建名需要 `{force: true}` 才能覆盖。

**单源原则**:form widget 的"权威注册表"在浏览器运行时的 form-registry.js 中,sys_shell 没有任何 widget 代码硬编码在 form-renderer.js 里——后者只是个 dispatcher。新增/修改 widget 只动 `<your_task>/static/`,其他 task 包零改动。

### 验证

```bash
Expand Down
80 changes: 76 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
</p>

<p align="center">
<a href="https://star-history.com/#MetaInfer/MetaInfer&Date">
<img src="https://api.star-history.com/svg?repos=MetaInfer/MetaInfer&type=Date" alt="Star History" width="600">
</a>
<a href="https://www.star-history.com/?type=date&repos=MetaInfer%2FMetaInfer">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=MetaInfer/MetaInfer&type=date&theme=dark&legend=top-left&sealed_token=7N_57a34GhT7taYXyy9U_E1V_9P1i7A_0PK4Am3dOHxXcNvtk9CuxadGB6B1ZCyS0Zsa2rq_z1U0OmRgz9YDhWs5IaomukOlrF5zq5eapw47cM1rYdOKnQ" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=MetaInfer/MetaInfer&type=date&legend=top-left&sealed_token=7N_57a34GhT7taYXyy9U_E1V_9P1i7A_0PK4Am3dOHxXcNvtk9CuxadGB6B1ZCyS0Zsa2rq_z1U0OmRgz9YDhWs5IaomukOlrF5zq5eapw47cM1rYdOKnQ" />
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=MetaInfer/MetaInfer&type=date&legend=top-left&sealed_token=7N_57a34GhT7taYXyy9U_E1V_9P1i7A_0PK4Am3dOHxXcNvtk9CuxadGB6B1ZCyS0Zsa2rq_z1U0OmRgz9YDhWs5IaomukOlrF5zq5eapw47cM1rYdOKnQ" />
</picture>
</a>
</p>

---
Expand Down Expand Up @@ -75,6 +79,14 @@

## Quick start

### Step 1: Install ccb (MetaInfer currently uses the open-source Claude Code CLI; other coding agents are not yet supported — contributions welcome)

Open-source ccb repository: https://github.com/claude-code-best/claude-code
```
npm i -g claude-code-best
```

### Step 2: Install MetaInfer
```bash
git clone https://github.com/MetaInfer/MetaInfer.git
cd MetaInfer
Expand All @@ -83,7 +95,7 @@ pip install -r requirements.txt
```

Open [http://127.0.0.1:8765](http://127.0.0.1:8765), click **+ New Task**,
pick a task type, describe your requirements, and the LLM gets to work.
pick a task type, fill in your requirements, and the LLM gets to work.

```bash
# Other ways to start
Expand All @@ -92,9 +104,69 @@ METAINFER_PORT=9000 ./serve.py
python -m metainfer.server.app
```

## Multi-node setup (optional)

The Quick Start above runs everything on one node. To run GPU workloads on
remote worker nodes (multi-task GPU isolation, cross-node PP2/TP debugging),
start a worker daemon on each GPU machine:

```bash
# On each worker node (must share the same NFS mount as the orchestrator):
pip install -r requirements.txt # same deps as the orchestrator
npm i -g claude-code-best # ccb needed for agent-type jobs

# Pick a stable node id (defaults to $METAINFER_NODE_ID or hostname)
METAINFER_ROOT=/shared/metainfer \
METAINFER_NODE_ID=gpu-worker-1 \
python -m metainfer.worker --ip 10.0.0.5
```

The worker registers itself in `cluster/workers/<node_id>.json` and starts
polling `cluster/inbox/<node_id>/` for jobs. It touches
`cluster/workers/<node_id>.heartbeat` every 15s — orchestrators and the
WebUI consider it dead if the heartbeat goes >60s stale.

From the WebUI's **Cluster** tab you can see registered workers, GPU
scoreboard (free/held per slot), and force-release any stuck slot. Tasks
that accept a `worker_nodes` form field (e.g. `evolve_kernel`,
`port_model`) will route GPU work to the listed workers when set.

Admin CLI:

```bash
metainfer-cluster workers ls # list workers + alive status
metainfer-cluster scoreboard show # show GPU claims across all workers
metainfer-cluster tail stdout gpu-worker-1 <job_id> # read a job's stdout
```

See `docs/multi-node-architecture.md` for the NFS-safe claim algorithm,
lease/reaper rules, and the single-reap-path invariant, and
`docs/agent-sdk-guide.md` for the SDK cookbook.

## License

MIT

## Academic Research

The initial ideas and experimental data of MetaInfer are publicly available
at https://arxiv.org/abs/2607.12875. The related code is on the `arxiv-paper` branch.

Citation:

```
@misc{miao2026metainferknowledgellminference,
title={MetaInfer: A Knowledge Only LLM Inference Engine Generator SKILL Toolbox},
author={Zhenwen Miao and Honglin Wang and Mingheng Mi},
year={2026},
eprint={2607.12875},
archivePrefix={arXiv},
primaryClass={cs.MA},
url={https://arxiv.org/abs/2607.12875},
}
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for architecture details, design
principles, and how to add new task types.
75 changes: 72 additions & 3 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
</p>

<p align="center">
<a href="https://star-history.com/#MetaInfer/MetaInfer&Date">
<img src="https://api.star-history.com/svg?repos=MetaInfer/MetaInfer&type=Date" alt="Star History" width="600">
</a>
<a href="https://www.star-history.com/?type=date&repos=MetaInfer%2FMetaInfer">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=MetaInfer/MetaInfer&type=date&theme=dark&legend=top-left&sealed_token=7N_57a34GhT7taYXyy9U_E1V_9P1i7A_0PK4Am3dOHxXcNvtk9CuxadGB6B1ZCyS0Zsa2rq_z1U0OmRgz9YDhWs5IaomukOlrF5zq5eapw47cM1rYdOKnQ" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=MetaInfer/MetaInfer&type=date&legend=top-left&sealed_token=7N_57a34GhT7taYXyy9U_E1V_9P1i7A_0PK4Am3dOHxXcNvtk9CuxadGB6B1ZCyS0Zsa2rq_z1U0OmRgz9YDhWs5IaomukOlrF5zq5eapw47cM1rYdOKnQ" />
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=MetaInfer/MetaInfer&type=date&legend=top-left&sealed_token=7N_57a34GhT7taYXyy9U_E1V_9P1i7A_0PK4Am3dOHxXcNvtk9CuxadGB6B1ZCyS0Zsa2rq_z1U0OmRgz9YDhWs5IaomukOlrF5zq5eapw47cM1rYdOKnQ" />
</picture>
</a>
</p>

---
Expand Down Expand Up @@ -75,6 +79,14 @@

## 快速开始

### 第一步,安装ccb。(本项目目前使开源的claude code版本,暂不支持其他coding agent,欢迎贡献代码以支持更多coding agent)

开源ccb项目地址:https://github.com/claude-code-best/claude-code
```
npm i -g claude-code-best
```

### 第二步,安装MetaInfer
```bash
git clone https://github.com/MetaInfer/MetaInfer.git
cd MetaInfer
Expand All @@ -92,8 +104,65 @@ METAINFER_PORT=9000 ./serve.py
python -m metainfer.server.app
```

## 多节点部署(可选)

上面的"快速开始"把所有工作放在同一台机器上。如果要把 GPU 任务派发到远端
worker 节点(用于多任务 GPU 隔离 / 跨节点 PP2/TP 调试),在每台 GPU 机器
上启动 worker daemon:

```bash
# 在每个 worker 节点(必须与编排器共享同一个 NFS 挂载):
pip install -r requirements.txt # 与编排器相同的依赖
npm i -g claude-code-best # agent 类 job 需要 ccb

# 选一个稳定的 node id(缺省取 $METAINFER_NODE_ID 或 hostname)
METAINFER_ROOT=/shared/metainfer \
METAINFER_NODE_ID=gpu-worker-1 \
python -m metainfer.worker --ip 10.0.0.5
```

worker 启动后会把自己写入 `cluster/workers/<node_id>.json`,并轮询
`cluster/inbox/<node_id>/` 等待任务。它每 15 秒 touch 一次
`cluster/workers/<node_id>.heartbeat`;编排器和 WebUI 发现心跳超过 60 秒
未更新就视作 worker 离线。

在 WebUI 的 **Cluster** 标签页可以查看已注册 worker、GPU scoreboard
(每个 slot 是 free/held)以及 force-release 卡住的 slot。支持
`worker_nodes` 字段的任务(如 `evolve_kernel`、`port_model`)在表单里
填写 worker 后会自动把 GPU 工作派发到指定节点。

管理 CLI:

```bash
metainfer-cluster workers ls # 列出 worker + alive 状态
metainfer-cluster scoreboard show # 显示所有 worker 上的 GPU claim
metainfer-cluster tail stdout gpu-worker-1 <job_id> # 读取某 job 的 stdout
```

架构细节(NFS-safe 原子 claim、租约/reaper 规则、单 reap 路径不变量)
见 `docs/multi-node-architecture.md`;agent-facing SDK 食谱见
`docs/agent-sdk-guide.md`。

## License

MIT

## 学术研究

MetaInfer的最初想法和实验数据已经公开在https://arxiv.org/abs/2607.12875,相关代码位于`arxiv-paper`分支。

引用信息:
```
@misc{miao2026metainferknowledgellminference,
title={MetaInfer: A Knowledge Only LLM Inference Engine Generator SKILL Toolbox},
author={Zhenwen Miao and Honglin Wang and Mingheng Mi},
year={2026},
eprint={2607.12875},
archivePrefix={arXiv},
primaryClass={cs.MA},
url={https://arxiv.org/abs/2607.12875},
}
```

## 如何贡献
架构细节、设计理念和新任务类型添加方法见 [CONTRIBUTING.md](CONTRIBUTING.md)。
Loading
Loading