Skip to content

第 0 课:建立可复现的实验环境 ​

先修知识 ​

会打开终端、切换目录和编辑文本即可。这一课不要求机器学习、线性代数或 GPU 知识。 你会看到少量 Python;所需语法会在代码旁解释。

本章建立的完整能力 ​

确认“正在运行哪一个 Python、依赖放在哪里、怎样重复一次小实验”。 之后模型输出有变化时,我们才有依据区分代码修改、数据变化、随机过程和环境差异。

预计 20–30 分钟,使用 CPU 和 Python 标准库,无需下载数据或模型。本课是准备课,脚手架是完整示范, 没有需要补写的 TODO,也不人为制造失败。

1. 先分清工具的职责 ​

工具或文件负责什么
Python执行实验代码的解释器
uv选择项目的 Python、创建虚拟环境、解析和安装依赖
.venv/当前仓库的 Python 运行环境,和其他项目隔离
.python-version请求使用 Python 3.12 系列
pyproject.toml声明项目允许的 Python 版本与直接依赖
uv.lock保存依赖解析结果,供后续按同一份记录安装
make把较长的命令包装成一致的入口

终端直接运行 python3 会按 PATH 寻找解释器,它不一定属于本仓库。 后续实验统一通过 make 或项目中的 uv run 执行,不依赖手动激活虚拟环境。

.python-version 固定的是 3.12 系列,不保证不同机器安装相同的补丁版本; 实际版本由自检输出记录。锁文件也不会固定硬件和操作系统。

2. 准备项目环境 ​

在仓库根目录运行:

sh
source ~/.zshrc
make setup

source ~/.zshrc 载入平时的 zsh 配置。make setup 执行 uv sync --frozen, 按已提交的锁文件准备 .venv/,不重新解析锁文件。第 0 课没有第三方依赖。 如果机器没有 Python 3.12,uv 可能先下载解释器。

如果提示找不到 uv,先按照 uv 官方安装说明 安装, 重新载入终端环境后再运行。依赖安装失败属于环境问题,不是课程练习的红灯。

3. 随机数为什么可以重复 ​

训练模型时,参数初始值和数据顺序经常包含随机选择。 计算机常用的伪随机数生成器按内部状态依次计算数值。 **种子(seed)**用于初始化状态;相同实现、相同初始状态和相同调用顺序,可以产生相同序列。

每抽取一次,生成器的内部状态就会向前推进。继续使用同一个生成器,不会自动回到初始状态。 数值本身仍可能碰巧重复,因此不能把“必须出现不同数字”当作随机性检查。

本课实验的核心代码如下。先阅读,不执行:

python
import random

first = random.Random(42)
second = random.Random(42)

sample_a = [first.randrange(10) for _ in range(5)]
sample_b = [second.randrange(10) for _ in range(5)]
continued = [first.randrange(10) for _ in range(5)]
  • import random 载入 Python 自带的随机数模块。
  • random.Random(42) 创建一个种子为 42 的独立生成器;first 和 second 各自保存状态。 42 只是本实验选用的整数,没有特殊含义。
  • randrange(10) 从整数 0 到 9 中抽取一个数,上界 10 不包含在内。
  • [表达式 for _ in range(5)] 是列表推导式:将表达式执行五次,把五个结果放进列表。 _ 是本例不会使用的循环变量。
  • continued 接着使用已经抽过五次的 first,没有创建新生成器。

完整文件 reproducibility.py 还用 print 打印结果、 用 == 比较两个列表是否逐项相同。def main(): 将步骤放进函数, 末尾的 if __name__ == "__main__": 在直接运行文件时调用它。这些组织代码由脚手架提供。

固定这里的种子只控制这两个 Python 生成器。未来的 PyTorch 随机过程需要单独设置, 设备、计算库版本和某些并行算法也会影响数值结果。

实验前预测 ​

在 学习记录 中先回答第 1 项:

sample_a 和 sample_b 应有什么关系?计算 continued 时,first 是继续原来的状态, 还是从种子重新开始?说明依据,不需要猜具体数字。

4. 运行一个贯穿实验 ​

sh
make check-tools

这个命令依次运行两步:

  1. 环境检查输出操作系统、架构、Python 版本、解释器和虚拟环境路径,并检查基础工具能否找到。
  2. 示范实验输出种子、三组样本和首两组是否相同。

成功时有 ENV: OK 和 REPRO: OK 两个标记,命令退出码为 0。 这些标记由课程脚本打印,分别表示当前环境符合要求、本次随机实验满足检查条件。

executable 应在当前仓库的 .venv/bin/ 下,environment 应指向当前仓库的 .venv。 解释器文件本身可能链接到 uv 管理的安装位置,这不妨碍它使用仓库虚拟环境。

把一次实际输出保留在笔记里,不需要逐字段抄写。随后再运行一次相同命令,观察三组样本是否复现。 每次都是新进程,程序会重新创建两个生成器;不要将它和同一进程里继续调用 first 混淆。

需要单独查看实验时,可以运行:

sh
uv run --frozen --no-sync python labs/lesson_00/reproducibility.py

这里的 --no-sync 表示直接使用已准备好的环境,因此前面必须先完成 make setup。

5. 结果与解释 ​

先对照预测:一致时写一句对应证据;不一致时保留原预测,另外记录实际结果与原因。

然后回答第 2 项:

把这个实验交给另一台机器上的人复现,除代码和种子外,还应该附上哪些环境信息? make check-tools 的绿灯是否足以证明未来的模型训练也可复现?说明检查覆盖到哪里。

本课只验证 Python 环境、基础工具和这个标准库实验。张量计算、梯度、GPU 后端和训练质量会由后续课程分别验证。

完成标准 ​

  • make check-tools 成功,能从输出识别本仓库使用的解释器与虚拟环境。
  • 两次运行的实际结果已比较,并留下预测、证据与必要修订。
  • 两个必答项有自己的解释,经导师审阅后再记录结课。

下一课从张量开始,把数据的数量、形状和批量计算对应起来。

配套阅读 ​

先理解,再实现;每个结论,都留下一条可重复的证据。