读完这篇,你能做什么
运行四种策略条件与五个训练种子,生成逐任务结果报告,解释验证集选型和测试集边界,并给出迁移真实小模型的复现清单。
学习理由、准备要求与知识点
为什么学它
研究要提出能被实验推翻的问题,建立公平对照并解释失败。代码和实验记录要能支撑结论,列出更多模型名称并不能替代这些工作。
先读这些内容
知识点清单
- 可证伪研究问题
- 冻结与全参数基线
- 低秩参数适配
- 验证集选择断点
- 输入消融
- 多随机种子与配对任务
- 成功率和成本的Pareto前沿
- 实验报告与复现边界
运行前先确认完整可运行的CPU研究练习:Python 3.14、PyTorch 2.9.1+cpu、Java 17。模型是八维输入、两动作输出的线性策略及低秩适配器;不是预训练语言模型,不代表完成真实LLM微调或多轮Agent基准。
01先弄懂它是什么
毕业实验可以从一个有明确输赢标准的问题开始:任务、训练数据和预算固定时,低秩适配能否减少可训练参数,同时提高一个冻结策略的任务成功率?这样输入、输出、对照组和失败条件都能检查。实验也可能发现没有提升,或参数省了、质量却下降了;这些都是需要如实写进报告的结果。
本篇用一个不需要下载模型的小环境练习完整流程。观测 x 有八个实数,根据 x0+0.7×x1-0.5×x2 是否大于零决定正确动作,动作空间为 {0,1},选对奖励一,否则零。这是一次观察后做一个决定的任务,用于检查模型适配和评测流程。规则已经公开,读者完全可以直接写程序求答案;使用神经模型是为了做可控实验,不能用这个任务的高成功率证明自然语言推理能力。
四种条件分别为冻结权重、全参数更新、rank=1低秩适配,以及低秩适配但移除第三个输入特征。最后一个条件用于检查策略是否依赖该任务信息,不是对LoRA机制优越性的证明。所有条件共享训练、验证、测试数据和固定基础权重;相同种子使用相同批次顺序,尽量避免把数据差异当成方法差异。
文中这几个词,先认一认
- 基线
- 在相同任务和预算下,用来比较新方法的明确做法。
- 消融
- 尽量保持其他条件相同,移除或替换一个因素,再看结果有什么变化。
- 实验单位
- 可以独立比较或抽样的任务、来源或运行。彼此相关的多条记录,不能简单当作多个独立样本。
02看看它怎么工作
先固定研究协议,再运行结果。训练集更新参数,验证集从预设的检查点中选择损失最低的状态,测试集只评价已经选定的状态。本例使用独立随机源生成三份数据,并给每条数据不同ID。真实语料还需要按用户、模板或文档来源分组去重;ID不同仅证明记录不同,不能证明语义没有泄漏。
输入X形状为[B,8],基础权重W0为[2,8]。低秩分支A为[1,8]、Bmat为[2,1],输出X×W0转置+(X×A转置)×Bmat转置。可训练参数为八加二,共十个,而全参数权重有十六个。
这个极小例子不保证节省实际运行内存或时间:算子开销、基础权重和优化器状态仍要计算,参数数量不是显存基准。 还要注意二分类Softmax只依赖两行权重之差,rank=1的增量(b1-b0)A已经能表示任意八维分类方向更新。
因此本实验比较参数化及优化行为,不能检验低秩约束导致的表达能力损失;研究容量瓶颈需要更丰富的输出空间和任务。
A随机初始化,Bmat初始化为零,因此初始低秩模型与冻结基线输出相同,同时Bmat可获得非零梯度。若两个因子都初始化为零,彼此梯度可能一开始也为零,学习无法启动。代码断言初始等价、基础权重没有被优化,以及结果始终落在合法动作集合,这些检查与最终准确率分开。
对五个训练种子分别保留完整结果,报告每种条件的平均成功率和运行间样本标准差。测试任务相同,比较方法时应使用配对差值;同一任务上的多个种子结果也相关,不能把五乘测试题数当作完全独立样本。需要推断到新任务时可按任务或任务家族重采样,再在报告中说明种子层面的不确定性。
最终报告至少包括问题与假设、数据来源与划分、方法和预算、选择规则、逐次运行结果、统计比较、成本及失败案例。本篇程序写出report.json,保留每个任务的动作和成功标记,便于后续复核。它不会替你生成“显著优于”的结论,也不因某个固定种子表现好就删掉其他运行。
先跑通一个最小例子
保存experiment.py,在PyTorch 2.9.1+cpu环境运行。脚本只生成本地小数据,训练线性策略并输出report.json;不会下载权重、访问外部工具或执行GPU训练。四条件×五种子均保留,数值由运行结果产生。
展开收起代码 · experiment.py
长行可在代码区域内左右滚动,按 Tab 可把焦点移入代码区。
import copy
import json
import statistics
from pathlib import Path
import torch
from torch import nn
from torch.nn import functional as F
torch.set_num_threads(1)
torch.use_deterministic_algorithms(True)
def dataset(seed, count, prefix):
generator = torch.Generator().manual_seed(seed)
x = torch.randn(count, 8, generator=generator)
y = (x[:, 0]+.7*x[:, 1]-.5*x[:, 2] > 0).long()
return x, y, [f"{prefix}-{i}" for i in range(count)]
train = dataset(1000, 128, "train")
valid = dataset(2000, 96, "valid")
test = dataset(3000, 128, "test")
assert not (set(train[2]) & set(valid[2]) or set(train[2]) & set(test[2]) or set(valid[2]) & set(test[2]))
base = torch.randn(2, 8, generator=torch.Generator().manual_seed(99))*.15
class Policy(nn.Module):
def __init__(self, mode):
super().__init__()
self.mode = mode
self.register_buffer("base", base.clone()) # 冻结数据,不交给优化器。
if mode == "full":
self.weight = nn.Parameter(base.clone())
elif mode.startswith("lora"):
self.a = nn.Parameter(torch.randn(1, 8)*.1)
self.b = nn.Parameter(torch.zeros(2, 1)) # 初始增量为零。
def forward(self, x):
if self.mode == "lora_without_feature":
x = x.clone()
x[:, 2] = 0 # 只消融输入信息,环境正确答案保持原定义。
if self.mode == "full":
return F.linear(x, self.weight)
scores = F.linear(x, self.base)
if self.mode.startswith("lora"):
scores = scores + F.linear(F.linear(x, self.a), self.b)
return scores
def run(mode, seed):
torch.manual_seed(seed)
model = Policy(mode)
params = list(model.parameters())
if mode == "lora":
assert torch.equal(model(train[0]), F.linear(train[0], base))
assert sum(p.numel() for p in params) == 10
if params:
optimizer = torch.optim.Adam(params, lr=.05)
generator = torch.Generator().manual_seed(seed+10000)
best_loss, best_state = float("inf"), None
for step in range(120):
indices = torch.randperm(len(train[1]), generator=generator)[:32]
optimizer.zero_grad()
loss = F.cross_entropy(model(train[0][indices]), train[1][indices])
assert torch.isfinite(loss)
loss.backward()
optimizer.step()
if (step+1) % 20 == 0:
with torch.no_grad():
score = F.cross_entropy(model(valid[0]), valid[1]).item()
if score < best_loss:
best_loss, best_state = score, copy.deepcopy(model.state_dict())
model.load_state_dict(best_state) # 选择规则完全不读取测试标签。
assert torch.equal(model.base, base)
with torch.no_grad():
actions = model(test[0]).argmax(-1)
assert set(actions.tolist()) <= {0, 1}
successes = actions.eq(test[1]).to(torch.int).tolist()
return {"mode": mode, "seed": seed, "trainable_parameters": sum(p.numel() for p in params),
"success_rate": statistics.mean(successes),
"tasks": [{"id": i, "action": a, "success": s} for i, a, s in zip(test[2], actions.tolist(), successes)]}
modes = ["frozen", "full", "lora", "lora_without_feature"]
results = [run(mode, seed) for mode in modes for seed in range(5)]
assert len(results) == 20 and all(len(r["tasks"]) == 128 for r in results)
assert {r["trainable_parameters"] for r in results if r["mode"] == "full"} == {16}
assert all(0 <= r["success_rate"] <= 1 for r in results)
summary = {mode: {"mean": statistics.mean(r["success_rate"] for r in results if r["mode"] == mode),
"seed_std": statistics.stdev(r["success_rate"] for r in results if r["mode"] == mode)} for mode in modes}
report = {"torch": torch.__version__, "scope": "synthetic one-step CPU policy; not LLM or multi-turn benchmark",
"protocol": {"train": 128, "valid": 96, "test": 128, "steps": 120, "batch": 32,
"checkpoint_rule": "minimum validation loss every 20 steps", "seeds": list(range(5))},
"summary": summary, "runs": results}
Path("report.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, indent=2))
print("PASS: 20 runs, 128 tasks each; report.json saved; no significance claim")
核对运行结果生成20次运行的report.json,每次128个测试任务,包含版本、协议、均值、种子标准差和逐题动作。低秩可训练参数为10,全参数为16;实验不预先假定哪一种方法一定胜出。 在上述固定CPU基线的一次复核中,五种子平均成功率依次为0.625、0.978125、0.9703125、0.865625;这些是合成任务结果,其他环境先核对版本与逐次输出。
正在加载流程图…
查看流程图源码(Mermaid)
flowchart TD
A["预先写问题与预算"] --> B["固定训练 验证 测试划分"]
B --> C["四种条件 五个种子"]
C --> D["仅验证集选择断点"]
D --> E["测试动作与逐题结果"]
E --> F["配对比较 成本 失败分析"]
F --> G["报告限制与复现材料"]按顺序看,每一步做了什么
- 冻结任务定义、数据与训练预算。
- 建立冻结、全参数和低秩三类基线。
- 一次只改变一个消融因素。
- 用验证集选择预定检查点,测试集仅做最终评价。
- 保存逐题动作与奖励,而不只保存均值。
- 报告不确定性、成本、失败和未验证范围。
03对照实现代码
PyTorch v2.9.1;LoRA论文arXiv:2106.09685 · Linear.forward → torch.nn.functional.linear;低秩增量BA
以下为原创低秩前向片段,调用真实F.linear;不是PyTorch自带LoRA层,不包含语言模型、量化或分布式训练。
from torch.nn import functional as F
def adapted_scores(x, frozen_weight, a, b):
original = F.linear(x, frozen_weight) # X[B,8]乘W0[2,8]的转置。
hidden = F.linear(x, a) # A[1,8]形成秩一中间表示。
delta = F.linear(hidden, b) # B[2,1]恢复两个动作分数。
return original + delta # 本实验缩放系数设为一。
固定版本Linear.forward将输入、weight和bias交给F.linear;权重形状为输出维乘输入维。本文利用同一个真实算子组合低秩分支,未复制或修改框架训练内核。维度推导可以独立检查每次矩阵乘法是否合法。
冻结基础权重并不等于删掉它:前向仍需要基础分支,因此模型总存储没有变成只有十个参数。真正大模型中的显存节省还取决于梯度、优化器状态和激活,不能从本例参数数目外推具体倍数。
优化器只接收model.parameters返回的可训练对象,base注册为buffer,随state_dict一起保存但不参与更新。实验断言基础矩阵保持不变,避免实现意外退化成全参数训练。
用deepcopy保存验证最优状态,避免后来更新覆盖“最佳”引用。选型完成后才读取测试结果;保存报告时把环境与选择规则一起写入,才能知道一次准确率对应哪个训练过程。
代码先调用谁,再调用谁
- Policy接收八维观测
F.linear计算基础动作分数- 两个
F.linear计算低秩增量 - 训练交叉熵更新可训练参数
- 验证损失选择状态副本
- 冻结策略输出动作并保存任务奖励
04动手写一个例子
从验证结果选出成功率与成本的Pareto前沿
给定同一验证集上的多组配置,每组有唯一ID、成功数量和正整数成本。若另一组成本不高、成功数不低且至少一项严格更好,该组被支配。返回未被支配配置;完全相同指标的不同配置全部保留。不要将测试结果用于此选型。
- 输入 1
A:80成功/成本10;B:85/20;C:75/30;D:85/15- 输出 1
A与D;B被D支配,C被A支配
- 输入 2
D:85/15;E:85/15- 输出 2
D、E都保留,指标完全相同不构成严格支配
先按成本升序排序,同成本按成功数降序、ID升序稳定排列。扫描某个成本组时,该组最高成功数支配同组所有更低成功数配置;指标完全一样的配置则同时保留,以免擅自加入未声明的偏好。
维护更低成本组已经达到的最大成功数best。如果当前组最高成功数不超过best,至少存在一个成本更低、成功数不差的配置,当前整组被支配。只有严格提高成功数时,组内所有最高分并列项进入前沿。
这一结论依赖比较的是同一组验证任务和同一种成本定义;不同样本量的成功数量不能直接排序。本算法只是整理观测结果,不计算置信区间,也不能证明很小的成功率差异具有统计意义。
为什么这样写是对的处理当前成本前,best是所有严格较低成本配置中的最高成功数,已经输出的配置彼此不能在这两个指标上支配。
排序K组配置占主导,随后各配置仅扫描一次;副本、ID去重和输出至多线性大小。成本与成功数使用固定宽度整数。
保存为 Main.java,运行 javac --release 17 -encoding UTF-8 Main.java,再运行 java Main。程序包含固定输入自测,断言失败时会抛出错误。
展开收起代码 · Main.java · 完整可运行程序
长行可在代码区域内左右滚动,按 Tab 可把焦点移入代码区。
import java.util.*;
public class Main {
record Trial(String id,int successes,long cost) {}
static List<Trial> frontier(List<Trial> input,int tasks){
if(input==null||tasks<=0)throw new IllegalArgumentException("tasks");
Set<String> ids=new HashSet<>();List<Trial> sorted=new ArrayList<>();
for(Trial t:input){
if(t==null||t.id()==null||t.id().isBlank()||!ids.add(t.id())||t.successes()<0||t.successes()>tasks||t.cost()<=0)
throw new IllegalArgumentException("trial");
sorted.add(t);
}
sorted.sort(Comparator.comparingLong(Trial::cost)
.thenComparing(Comparator.comparingInt(Trial::successes).reversed()).thenComparing(Trial::id));
List<Trial> out=new ArrayList<>();int best=-1;
for(int i=0;i<sorted.size();){
int end=i+1;long cost=sorted.get(i).cost();int top=sorted.get(i).successes();
while(end<sorted.size()&&sorted.get(end).cost()==cost)end++; // 按相同成本成组处理。
if(top>best){
for(int j=i;j<end&&sorted.get(j).successes()==top;j++)out.add(sorted.get(j)); // 完全并列均保留。
best=top;
}
i=end; // 较低成本已达到同等成功数时,当前整组被支配。
}
return out;
}
static void check(boolean ok){if(!ok)throw new AssertionError();}
static void bad(Runnable r){try{r.run();}catch(IllegalArgumentException e){return;}throw new AssertionError();}
public static void main(String[] args){
List<Trial> all=List.of(new Trial("A",80,10),new Trial("B",85,20),new Trial("C",75,30),new Trial("D",85,15));
check(frontier(all,100).stream().map(Trial::id).toList().equals(List.of("A","D")));
check(frontier(List.of(new Trial("D",85,15),new Trial("E",85,15)),100).size()==2);
check(frontier(List.of(new Trial("x",0,1),new Trial("y",0,2)),100).size()==1);
check(frontier(List.of(),100).isEmpty());
bad(()->frontier(List.of(new Trial("x",101,1)),100));
bad(()->frontier(List.of(new Trial("x",1,0)),100));
bad(()->frontier(List.of(new Trial("x",1,1),new Trial("x",2,2)),100));
check(all.get(0).id().equals("A"));
System.out.println("PASS 8 Pareto checks");
}
}这些特殊情况也要试一试
- 所有成功数为零时,仅最低成本组保留。
- 完全相同指标允许不同配置同时存在。
- 重复ID、非法成功数、非正成本拒绝。
- 比较必须使用同一验证集与成本口径。
进阶选读 · 多指标与不确定性下的实验选择
场景同时比较成功、延迟、成本、显存与失败风险。
做法先定义必须满足的约束,再对可行配置分析前沿。三个以上指标不能直接套用此二维扫描;同时保留置信区间与任务子群结果,避免把噪声差异当作支配关系。
复杂度D维朴素两两比较为O(DK²),可按具体维数与数据结构优化;额外重复实验成本另计。
好处与代价更多指标更贴近真实部署,但排序不再唯一,需要明确偏好和可靠性约束。
05项目里怎么用
迁移到真实语言模型时,先选定可复核的模型版本和许可,锁定分词器、模板、数据快照和评测环境。沿前篇SFT与LoRA训练流程保存完整脚本,再增加一项明确的Agent能力,例如工具选择或检索决策;一次只改变一个研究因素。不要同时换模型、提示、检索库和评测器后把提升归因于某个算法。
模型适配实验与Agent系统实验分别验收,再连接端到端结果。前者检查有效Token、损失、可训练参数及保留集质量;后者检查工具参数、状态恢复、预算与任务成功。加入冻结模型、确定性规则或检索基线,确认训练的额外成本解决了什么问题。DPO或GRPO需要相应的偏好或可验证奖励数据,不能为了覆盖名词强行堆叠。
毕业交付应包括一条从空环境到报告的命令链、锁定依赖、脱敏数据或生成器、所有种子与配置、逐题结果、统计脚本、至少一种消融和失败分类。真实GPU显存、吞吐、多轮成功率只有实际执行后才能填写;本篇CPU结果不能替代它们。读完博客提供方法基础,完成这些可复核材料才是研究实践的证据。
容易踩的坑
- 从测试集反复选择最好模型。
- 只保留最佳种子而不报告全部运行。
- 把参数少直接等同训练更快或显存更低。
- 把合成线性任务成功率描述成语言模型能力。
- 消融同时改变数据、预算和模型,无法解释原因。
几种做法,怎么选
表格有四列,窄屏可左右滑动查看代价和适用条件。
| 方案 | 优势 | 代价与限制 | 适用条件 |
|---|---|---|---|
| CPU机制实验 | 成本低、易于核对与复现 | 缺乏真实语言和系统复杂度 | 验证公式、实现和实验管线 |
| 真实小模型受控研究 | 可评价自然语言与实际任务迁移 | 需要数据许可、算力预算与更细致审计 | 形成可展示的研究作品 |
| 大规模训练或复杂多Agent | 覆盖更广能力与运行边界 | 昂贵且容易混入多个变量,需要成熟基线 | 小实验和评测协议已稳定的后续阶段 |
06检验是否读懂了
先自己想、自己写,再展开答案核对。场景题是假设的练习情境;遇到还没学过的内容,可以做完基础后再回来。
先用自己的话解释
01为什么研究问题必须允许“没有提升”?
展开参考答案与推导
若任何结果都能被解释成成功,问题就无法被证伪。预先写指标和对照条件,才有可能区分证据与选择性叙述。
02本例十个可训练参数是否说明内存只需十个数?
展开参考答案与推导
还保存基础矩阵、输入、激活、梯度与优化器状态;低秩分支改变训练参数,不会消除全部计算和存储。
03移除输入特征的消融能证明LoRA优于全参数训练吗?
展开参考答案与推导
不能。它检查对信息的依赖,算法比较仍需同输入、同预算和明确选择规则的独立对照。
换个情况,还会处理吗
01五个种子中只有一个显著提升,报告怎么写?
展开参考答案与推导
保留全部运行并报告分布,检查异常种子与失败任务,提出后续假设;不删除差结果或只引用最好值。
02成本更低但成功率略差,如何选型?
展开参考答案与推导
先确认差异的不确定性和业务约束,再查看验证集上的Pareto前沿;部署选择由允许的质量损失和预算决定,不能仅看单一榜单。
03真实工具环境更新后复现实验失败,怎么办?
展开参考答案与推导
记录环境版本与变化,区分模型回归和环境漂移;保存可重放的小环境或快照,重新建立基线后再比较。
写代码试一试
01为report.json增加同任务的配对差值。
- 输入 / 条件
同一种子A成功[1,0,1],B成功[1,1,0]- 输出 / 预期
B-A=[0,1,-1],均值0
提示 先按任务ID对齐,再计算差值。
展开参考答案与推导
拒绝缺失或重复ID,以固定集合join结果;保留每题差值,后续bootstrap按任务重采样,不能独立打乱两种方法。
02把Pareto算法扩展到延迟约束。
- 输入 / 条件
A:80/10/延迟40;D:85/15/延迟70;上限50- 输出 / 预期
仅A进入可行前沿
提示 先检查硬约束再比较两个目标。
展开参考答案与推导
过滤超过延迟上限的配置,记录排除原因,再对可行配置调用frontier。若没有可行解应返回明确状态。
03设计训练数据泄漏审计。
- 输入 / 条件
train文档d1的改写出现在test,ID却不同- 输出 / 预期
发现来源家族重叠,当前划分不可作为独立测试证据
提示 ID去重之外保留来源关系与近重复线索。
展开参考答案与推导
按原始文档或模板家族分组划分,结合规范化哈希和人工审计;重划分后重新训练和评测,不能只删除失败测试题。
读完之后,独立完成
课后作业:自己做一遍
本篇共 12 道作业,先完成 9 道基础与综合任务,再按前置知识挑战进阶题。其中包含 2 道思维拓展,试着换个条件,看看原来的办法是否还管用。不附参考答案。
运行四种策略条件与五个训练种子,生成逐任务结果报告,解释验证集选型和测试集边界,并给出迁移真实小模型的复现清单。
本篇重点加练
毕业研究的价值在可证伪问题、可靠比较与可复核证据,增加针对研究设计失效的考核。
- 可证伪研究问题
- 多随机种子与配对任务
- 实验报告与复现边界
重点内容会多练几次。先说清楚怎么做,再试试空数据、出错或条件改变时会发生什么。
先自己做,卡住时记下问题,再回来查。问答题写清“为什么、什么时候适用”;动手题留下输入、输出和运行步骤,方便下次重做。
基础必做
- 作业 01原理问答
提出一个可能被结果否定的小模型适配假设,写出支持、反对和证据不足三种结果的判定标准,并说明实验能力边界。
- 提交内容
- 一页研究预注册
- 怎样算完成
- 假设具体可测
- 零结果有明确处理
练到的知识点可证伪研究问题 · 实验报告与复现边界
- 作业 02代码推演
为输入维度 5、输出类别 3 的小策略设计冻结、全参数及两个低秩配置,列参数与检查点选择规则,说明表达约束如何检验。
- 提交内容
- 方法表与选型契约
- 怎样算完成
- 基础参数身份一致
- 验证集与测试集职责分开
练到的知识点冻结与全参数基线 · 低秩参数适配 · 验证集选择断点
- 作业 03原理问答
为自己的研究列出三个可能互相竞争的解释,例如优化、数据差异和评价器偏差;为每个解释指定能支持或削弱它的观测。
- 提交内容
- 竞争假设与证据矩阵
- 怎样算完成
- 解释可区分且可检验
- 没有预先指定胜出方法
练到的知识点可证伪研究问题 · 实验报告与复现边界
综合应用
- 作业 04编程实践
完成 CPU 合成决策任务实验,至少四种配置、五个预定种子,导出逐任务预测、训练轨迹和验证选择记录。
- 提交内容
- 可复现代码与原始结果
- 怎样算完成
- 全部运行可追溯
- 配对任务身份一致
练到的知识点冻结与全参数基线 · 低秩参数适配 · 验证集选择断点 · 多随机种子与配对任务
- 作业 05排错实验
对一个被认为关键的输入因素做受控消融,同时保留一个无关因素对照;检查数据和预算是否因消融被意外改变。
- 提交内容
- 两类消融与审计报告
- 怎样算完成
- 干预只改变声明因素
- 负对照作用明确
练到的知识点输入消融 · 多随机种子与配对任务
- 作业 06设计评审
把全部配置放到同一成功率—成本比较图中,写出候选选择与不确定性说明;成本至少包含一种实际测量量。
- 提交内容
- 比较图、测量记录与决策说明
- 怎样算完成
- 成本单位可比较
- 观测支配不等同统计显著
练到的知识点成功率和成本的Pareto前沿 · 实验报告与复现边界
- 作业 07编程实践
实现结果完整性审计器,核对每个预定配置×种子×测试任务是否恰有记录;注入缺失、重复和配置摘要不一致三类数据。
- 提交内容
- CPU 审计代码与故障报告
- 怎样算完成
- 实验计划作为外部基准
- 异常记录不会默默删除
练到的知识点多随机种子与配对任务 · 实验报告与复现边界
- 作业 08设计评审
预算不足以再跑全部设置时,预先选择一次追加实验来区分两个竞争解释;写明选择理由及看见结果后允许作出的结论。
- 提交内容
- 有限预算实验决策书
- 怎样算完成
- 信息目标明确
- 不以最容易得到正结果为规则
练到的知识点可证伪研究问题 · 多随机种子与配对任务
- 作业 09排错实验
故意只报告每种方法最好的种子,再与全部预定种子报告比较;保留相同逐任务配对,说明结论变化源于哪一步分析选择。
- 提交内容
- 选择偏差审计及双报告
- 怎样算完成
- 原始结果不被改写
- 配对任务与种子层次分开
练到的知识点多随机种子与配对任务 · 实验报告与复现边界
进阶挑战 · 掌握前置后选做
- 作业 10面试场景
为毕业报告安排一次独立复核:另一人从空环境执行命令并重建主要表格;若迁移真实语言模型,列出新增数据、算力与评价证据。
- 提交内容
- 复现说明与复核记录模板
- 怎样算完成
- 所有结果有生成路径
- 未完成迁移明确标为待验证
练到的知识点可证伪研究问题 · 输入消融 · 实验报告与复现边界
思维拓展
先写出你的猜想,再用例子或实验验证。答案可以不同,但要说清依据、适用情况,以及还有什么没弄懂。
- 作业 11思维拓展 · 开放探究
如果完整研究得到无提升,怎样判断它是有价值的负结果、检验力不足还是实现未生效?为三种情形设计不同证据链。
- 提交内容
- 负结果判定树与验证需求
- 怎样算完成
- 无提升不直接等于等价
- 机制生效和效果证据分开
练到的知识点可证伪研究问题 · 实验报告与复现边界
- 作业 12思维拓展 · 跨域迁移
把 CPU 合成任务结果迁移到真实小语言模型时,哪些因果解释最可能失效?提出分阶段实验,每阶段限定数据、算力和实际验证范围;无设备不填实测结果。
- 提交内容
- 迁移假设表与阶段验收
- 怎样算完成
- 合成与真实证据分层
- 新增混杂因素有控制计划
练到的知识点多随机种子与配对任务 · 实验报告与复现边界
完成后,再检验一次
给每题标记“独立完成 / 查阅后完成 / 尚未完成”。查过资料或没做出的题,记下卡在哪里。隔一天换一组输入再试,能解释结果和出错原因,再把这个知识点标为掌握。
继续阅读
先看能帮你完成当前练习的部分。例子跑通后,再读更深入的解释。
- 必读参考文档英文
LoRA原论文 (新标签页)↗
阅读低秩参数化、初始化和实验比较,并区分本篇线性玩具模型与论文语言模型实验。
- 实践参考文档英文
PyTorch v2.9.1 Linear源码 (新标签页)↗
核对参数布局与
F.linear调用,理解本篇组合的真实算子。 - 实践参考文档英文
PyTorch 2.9复现说明 (新标签页)↗
理解随机数、确定性算子与跨平台复现的边界。
- 深入参考文档英文
NeurIPS论文检查表 (新标签页)↗
用声明、限制、计算资源与实验复现条目审查自己的研究报告;提交时再核对对应年度要求。