# GPU 实验最佳实践（算法工程师清单）

面向：你自备 GPU / 密钥；本包**不跑训练**。命令为建议伪命令，需按你环境改路径。

时区：Asia/Hong_Kong。

---

## 阶段 0 — 钉死环境

```bash
# 建议：独立 venv + 锁版本
python3.12 -m venv .venv && source .venv/bin/activate
pip install "torch==2.7.*" --index-url https://download.pytorch.org/whl/cu128  # 例：对齐 RSI 卡栈需核对
pip install transformers peft datasets accelerate trl sentencepiece
# Qwen3.5 DeltaNet：按底座说明安装 fla 等；版本写进 requirements.lock
nvidia-smi > runs/env_nvidia.txt
python -c "import torch; print(torch.__version__, torch.cuda.get_device_name(0))" | tee runs/env_torch.txt
```

Checklist：

- [ ] CUDA / torch / transformers / peft 版本写入 `runs/env_*.txt`
- [ ] 随机种子固定（例：`20260922` 论文；QJev `seed=42`）
- [ ] 关闭无关自动下载镜像差异；记录 `HF_HUB_REVISION`

---

## 阶段 1 — 选型（只选一条主路径 + 一条对照）

**推荐主路径（中英 0.8B）**

- 底座：`Qwen/Qwen3.5-0.8B`（instruct，与 QJev 一致）或 `…-Base`（与 Kev/RSI 一致）——**不要混用再比数字**。
- 读出：**字母 logprob + 双向平均**（跟 QJev）或 **编号 prefill**（跟 LLM-as-Jev）二选一写进实验卡。
- 适配：LoRA r=16~32，α=2r，dropout 0；目标模块含 attn/MLP（及 DeltaNet 投影若存在）。

**对照路径（免训练）**

```bash
# 伪：对同一批 held-out，用底座 + Best answer: [ 后缀打分
python scripts/score_llm_as_jev.py --model Qwen/Qwen3.5-0.8B --tasks data/heldout.jsonl
```

---

## 阶段 2 — 数据

```bash
huggingface-cli download ZY-Lee4/QJev3.5-mix --repo-type dataset --local-dir data/qjev-mix
# 只用发布子集；确认无 ANLI 行
rg -n 'anli|ANLI' data/qjev-mix -g '!*.md' || true
```

门禁脚本建议自写：

1. **泄漏**：相对 JevBench 公开 JSONL，13-word n-gram / ≥6 词整句重叠 → drop（论文协议）。
2. **位置**：答案字母/index 边缘分布 ≈ 均匀；拒绝「末位率随 K 可预测」。
3. **类别绝对计数**：每个 family × label 的 min count；中文正例单独计数。
4. **接地**：gold 实体必须出现在 state（QJev 踩过的坑）。
5. **冲突**：同 state 不同 gold → drop。
6. **选项 shuffle**：训练 dataloader 每行置换；推理评估 canonical + reversed。

```bash
python scripts/audit_dataset.py --train data/train.jsonl --jevbench datasets/public/*.jsonl --fail-on-leak
```

许可：

- [ ] 不重分发 ANLI（NC）
- [ ] ReClor / NC-SA 源仅研究、不进商业权重声明
- [ ] 不把官方 Jev API 蒸馏当「开源数据」再分发

---

## 阶段 3 — 训练

### 字母 QLoRA 起点（贴 QJev）

```bash
# 伪命令 — 需自备 train_lora.py
python train_lora.py \
  --base Qwen/Qwen3.5-0.8B \
  --data data/qjev-mix/v8/train.jsonl \
  --val data/qjev-mix/v8/val.jsonl \
  --lora-r 32 --lora-alpha 64 \
  --lr 1e-4 --epochs 1 \
  --batch 8 --grad-accum 2 \
  --max-len 4096 \
  --bf16 --gradient-checkpointing \
  --chat-template-kwargs '{"enable_thinking": false}' \
  --shuffle-options \
  --seed 42 \
  --out runs/qjev-repro-001
```

### LLM-as-Jev 风格起点（论文表 3）

| 项 | 建议 |
|----|------|
| LoRA | r16 α32 dropout0 |
| LR | LoRA 1e-4；全参 0.8B 级可试 5e-6 |
| Batch | 全局 32（显存不够则 accum） |
| Epoch | **≤1**；看 OOD 而非 train loss |
| λ | KL 锚默认 1；无锚先别发 |
| 健康 | 合法 mass 崩 → 停 |

Intent-only 长训会养 yes 偏置（论文）：**格式多样 + 适量 long** 优于堆 intent epoch。

---

## 阶段 4 — 评测协议

分层报告，禁止混列：

| 层 | 集 | 用途 |
|----|----|------|
| A | 自建 / QJev seed_ext 等**明确 held-out 家族** | 产品决策 |
| B | LocalLLaMA typed-decisions **test**（若未训 train） | 跨工作流 |
| C | JevBench **公开 231** | **仅诊断**；披露是否见过 |
| D | 外部公开分类（Banking77 全类、BoolQ…） | 泛化 |

指标：Acc、ECE（15 bins）、Brier、选项顺序 gap、中文子集、合法解析率、p50/p95 延迟、VRAM。

```bash
python scripts/eval_letter.py --ckpt runs/… --tasks A B --two-pass-swap
python scripts/eval_jevbench_public.py --ckpt runs/… --disclose train_leak=false
```

Checkpoint 选择：**只用 A/B**，不用 C。

---

## 阶段 5 — 成本与延迟

- 固定：同卡、同 batch=1、同 prompt 长度桶、预热后 p50。
- 报：ms/decision、decision/s、峰值显存、量化后 fidelity（答案一致率）。
- QJev 卡参考：3080 Ti 级约 **68–150 ms**（两遍）；Kev L4 短状态多题约 **16–23 ms**（卡测）。你的数字必须自测。

---

## 阶段 6 — 发布诚实声明（模板）

> 本权重为第三方 Jev-style 复刻，**非 TypeSafe 官方**，与 TypeSafe / Jev 无隶属。  
> 底座：… 许可：…  
> 训练数据：…（列出 HF id；已排除 ANLI 再分发；未使用 / 已使用官方蒸馏 —— 二选一如实写）。  
> 评测：产品 held-out …；JevBench 公开 …（仅诊断，未参与选模）；sealed 未测。  
> 已知限制：K≤26（若字母）；OOD ECE 高；中文仅覆盖 … 家族。

---

## 若只跑一个实验的最短路径

1. 下载 QJev3.5-mix 可再分发子集 + Qwen3.5-0.8B  
2. 审计泄漏与位置均匀  
3. LoRA 1 epoch，thinking off，shuffle options  
4. 评估：mix val + 自建中文 gate/noul + typed-decisions test（未训）+ JevBench 公开（诊断）  
5. 对照：同底座免训练 LLM-as-Jev 编号打分  
6. 写卡：域内 / 域外分列；不宣称「超越官方 Jev」除非同协议复现
