Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Summary

<!-- What does this PR add or change? -->

## Trace provenance (when applicable)

- Model and revision:
- GPU and dtype:
- Layer and estimator:
- Language / concept:
- Demo or preview:

## Validation

- [ ] `python experiments/validate_trace_gallery.py`
- [ ] `pytest -q`
- [ ] `cd apps/web && npm ci && npm audit --audit-level=high && npm run build`
- [ ] No model weights, caches, secrets, personal data, or restricted prompts
- [ ] Frontend displays baked rigor values and does not recompute sharedness
44 changes: 44 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Validate code and traces

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml

- name: Install Python package and test runner
run: python -m pip install -e . pytest

- name: Validate committed trace gallery
run: python experiments/validate_trace_gallery.py

- name: Run Python tests
run: pytest -q

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: apps/web/package-lock.json

- name: Build web application
working-directory: apps/web
run: |
npm ci
npm audit --audit-level=high
npm run build
73 changes: 73 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Contributing to J7Scope

感谢你帮助扩展跨语言 J-space trace。最有价值的贡献是:可复现、明确标注局限、不会把
preview 当作研究结论的真实模型采集。

## 快速路径:Colab 采集

1. 在 Google Colab 打开 `notebooks/capture_colab.ipynb`。
2. 选择 **Runtime → Change runtime type → GPU**。
3. 按顺序运行所有 cell,填写 prompt、语言、概念和唯一 `trace_id`。
4. 下载 notebook 生成的 ZIP,在本地解压。

默认 Qwen2.5-1.5B + 少量随机探针用于验证贡献流程,产物会标记
`preview: true`,不是可引用的 M1 证据。GPU 型号、dtype、模型 revision、Jacobian
estimator 和张量 SHA-1 会写进 manifest。

也可以在任何 CUDA 机器直接运行:

```bash
pip install -e .
python experiments/capture_trace.py \
--trace-id community-deception-en \
--language en \
--concept deception \
--prompt "In one sentence, explain why deception can be tempting."
```

先用 `--dry-run` 检查配置,不会下载模型或占用 GPU。

## Trace 命名与内容

- `trace_id`:1–80 个小写字母、数字、点、下划线或连字符;建议
`community-<concept>-<lang>-<short-id>`。
- prompt 不得包含个人信息、机密内容、API key 或未获许可的数据。
- 模型必须是贡献者有权使用和重新发布派生小型 artifact 的权重。
- 不提交模型权重、Jacobian `.pt`、Hugging Face cache 或其他大文件。
- 不手工修改 `tokens.jsonl` 中的 `rigor.sharedness`。严谨层只能由
`j7scope.rigor` 生成。
- 社区 trace 默认保留 `preview: true`;研究级标记由维护者在复核协议、语料和
estimator 收敛后处理。

## 加入 Gallery

把完整 trace 目录复制到 `results/traces/<trace_id>/`,然后从仓库根目录运行:

```bash
python -c "from j7scope.trace import rebuild_trace_index; rebuild_trace_index('results/traces')"
python experiments/validate_trace_gallery.py
pytest -q
```

提交 `manifest.json`、`tokens.jsonl`、`metrics.json`,以及平行 trace 才需要的
`align.json`。同时提交重建后的 `results/traces/index.json`。

## Pull request 检查清单

- [ ] Trace 在本地通过 `experiments/validate_trace_gallery.py`
- [ ] `trace_id` 与目录名一致且 index 已重建
- [ ] `is_demo` / `preview` 标记真实准确
- [ ] manifest 含 model revision、dtype、device、estimator 和 Jacobian SHA-1
- [ ] prompt 和 artifact 不含个人、机密或受限信息
- [ ] 未提交模型权重、cache 或大型二进制
- [ ] PR 描述说明模型、GPU、语言、概念和采集目的

## Code contributions

Python 变更应补测试;前端不得重算 sharedness/null 指标,只显示 trace 中已烤入的值。
运行:

```bash
pytest -q
cd apps/web && npm ci && npm audit --audit-level=high && npm run build
```
71 changes: 69 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,69 @@ h_en = jlens.collect_residual(pairs["deception-01"]["en"]["text"])
print(jlens.readout(h_zh), jlens.readout(h_en)) # 两种语言的读出一致吗?
```

### 8.1 J-Space Explorer 前端(离线 artifact)
在投入 7B GPU 采集前,可先在随机初始化的 tiny-Qwen2 上复跑 Jacobian 数学一致性检查;
它不下载模型,也不产生研究结论:

```bash
python experiments/validate_jacobian.py --n-probes 4096
```

报告中的 `exact_vs_full_graph` 比较 `torch.func.jacrev` 尾部重放与独立的全模型逐维
VJP,`paper_batched_vs_scalar_vjp` 检查上游 replicated-batch position reduction 与
逐标量实现,两者
都应该接近数值零误差;`stochastic_vs_exact` 则量化当前随机探针估计的有限样本误差。
当前 capture 路径拟合的是 cloze 的同位置 `∂h_L[p]/∂h_l[p]` 变体;
`estimate_jacobian_paper` 才会汇总未来 target positions。正式 P3 运行前必须先锁定并记录
所用口径。

上游预训练 lens 的云 GPU 复现入口已经固定到发布时使用的 Qwen3.5-4B 配置:

```bash
pip install -e '.[upstream]'
python experiments/reproduce_upstream.py --preflight-only
python experiments/reproduce_upstream.py
```

正式 paper estimator 的拟合入口支持显存预检、运行计时、峰值显存记录以及逐 prompt
原子 checkpoint。默认仓库语料仅用于 smoke test,不是研究证据;正式运行流式抽取
WikiText 1000 条:

```bash
pip install -e '.[fit]'
python experiments/fit_paper_jacobian.py --dry-run
python experiments/fit_paper_jacobian.py --preflight-only
python experiments/fit_paper_jacobian.py \
--dataset Salesforce/wikitext \
--dataset-config wikitext-103-raw-v1 \
--max-prompts 1000 --min-chars 200
```

中断后原命令重跑会从 `results/*.checkpoint.pt` 续传,并校验模型、层、estimator 参数和
完整有序语料 SHA-1。最终 `*.pt` 是可直接传给 sidecar `--jacobian-file` 的 float32
矩阵,同名 JSON 保存模型 revision、硬件、耗时、峰值显存和 tensor SHA-1。

在线 GPU 选型、Runpod 操作、Colab 边界和学术 credits 申请步骤见
[`docs/gpu-cloud-runbook.md`](docs/gpu-cloud-runbook.md);英文申请底稿见
[`docs/gpu-credit-proposal.md`](docs/gpu-credit-proposal.md)。

### 8.1 社区 GPU / Colab 采集

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/arthurpanhku/j7scope/blob/main/notebooks/capture_colab.ipynb)

Colab notebook 用 Qwen2.5-1.5B-Instruct 采一条自定义真实模型 trace,自动适配 T4 的
`float16` 与新 GPU 的 `bfloat16`,完成 schema/provenance/rigor 校验后下载 ZIP。默认
产物明确标为 `preview`,不作为研究证据。任何 CUDA 机器也可直接运行:

```bash
python experiments/capture_trace.py \
--trace-id community-deception-en \
--language en --concept deception \
--prompt "In one sentence, explain why deception can be tempting."
```

提交步骤和数据边界见 [`CONTRIBUTING.md`](CONTRIBUTING.md)。

### 8.2 J-Space Explorer 前端(离线 artifact)

`apps/web` 是离线浏览已跑完实验 run 的前端,读取 `results/runs/<run_id>/` 下一组稳定 artifact(`manifest.json` / `readouts.jsonl` / `patches.jsonl` / `projections.json` / `layer_scan.json` / `metrics.json`)。本地开发可先生成一个明确标记为 demo 的假数据 run:

Expand All @@ -239,8 +301,13 @@ cd apps/web && npm install && npm run dev -- --port 5173
- [x] P1 Trace schema v1 + `--record` + Replay 回放模式(mock 可验证,零 GPU)
- [x] P2 静态 Gallery 站(Gallery/Replay/Compare + 深链 + 导出 SVG/PNG/JSON/BibTeX + Pages 部署工作流)
- [ ] P3 首批真实 trace + Zenodo DOI(与 M1 首批数据合并一次租卡)
- [ ] P4 Colab 采集笔记本 + 社区提交流程
- [x] P4(实现)Colab 自定义采集 + T4 dtype 适配 + 贡献规范/模板 + trace CI
- [ ] P4(验收)首个外部贡献者产出并合入通过 CI 的 preview trace
- [x] P5(切片)跨会话 cross-trace 指标 + 并排对齐高亮 + null 带 + 方法学页(可展开审计)
- [x] P3 前置(切片)精确 position-local Jacobian + upstream paper reduction + tiny-Qwen2 数学校验
- [x] P3 前置(切片)固定上游 Qwen3.5-4B/lens revision 的云 GPU 复现脚本与显存预检
- [x] P3 前置(实现)replicated-batch 正式 fitter + 原子 checkpoint/resume + WikiText 入口
- [ ] P3 前置(剩余)在云 GPU 执行上游已知案例并据实锁定正式拟合口径

**研究线(M1–M3)**

Expand Down
11 changes: 10 additions & 1 deletion apps/serve/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,18 @@ generated token's residual is read out through it.
```bash
python -m j7scope_serve --backend hf \
--model Qwen/Qwen2.5-7B-Instruct --layer 18 \
--jacobian-cache ~/.cache/j7scope
--model-revision main --dtype auto \
--jacobian-file ../../results/jacobian-qwen2.5-7b-l18.pt
```

`--jacobian-file` 直接加载
[`experiments/fit_paper_jacobian.py`](../../experiments/fit_paper_jacobian.py)
生成的正式矩阵;省略它时才会用小语料和随机 position-local estimator 临时拟合,可通过
`--jacobian-cache` 缓存,但这种快速路径只适合 wiring/preview,不应当作为研究结果。
`--dtype auto` 在支持 BF16 的 CUDA GPU 上选择 `bfloat16`,在 T4 等旧卡上选择
`float16`,CPU 则选择 `float32`。录制 manifest 会保存解析后的模型 revision、实际
device/dtype、estimator 和 Jacobian SHA-1。

## Record & replay (platform P1)

Live sessions are ephemeral; **traces** are the citable, deep-linkable artifact
Expand Down
13 changes: 12 additions & 1 deletion apps/serve/j7scope_serve/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,17 @@ def main() -> None:
p.add_argument("--token-delay", type=float, default=0.04,
help="seconds between streamed tokens (mock pacing / demo feel)")
p.add_argument("--device", default=None, help="hf: torch device override")
p.add_argument("--dtype", choices=["auto", "bfloat16", "float16", "float32"],
default="auto", help="hf: model dtype (auto handles T4 vs newer GPUs)")
p.add_argument("--model-revision", default="main",
help="hf: Hugging Face model branch, tag, or commit")
p.add_argument("--max-new-tokens", type=int, default=256, help="hf: generation cap")
p.add_argument("--jacobian-cache", default=None,
help="hf: directory to cache the fitted Jacobian")
p.add_argument("--jacobian-file", default=None,
help="hf: precomputed Jacobian tensor from the paper fitter")
p.add_argument("--jacobian-metadata", default=None,
help="hf: fitter metadata JSON (default: same stem as tensor)")
p.add_argument("--record", default=None, metavar="DIR",
help="record each session as a Trace v1 under DIR/<trace_id>/")
p.add_argument("--traces", default=None, metavar="DIR",
Expand All @@ -50,7 +58,10 @@ def main() -> None:
kw["model_name"] = args.model
if args.backend == "hf":
kw.update(device=args.device, max_new_tokens=args.max_new_tokens,
cache_dir=args.jacobian_cache)
cache_dir=args.jacobian_cache, dtype=args.dtype,
model_revision=args.model_revision,
jacobian_path=args.jacobian_file,
jacobian_metadata_path=args.jacobian_metadata)
kw.setdefault("model_name", "Qwen/Qwen2.5-7B-Instruct")

backend = make_backend(args.backend, **kw)
Expand Down
Loading
Loading