第 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. 准备项目环境
在仓库根目录运行:
source ~/.zshrc
make setupsource ~/.zshrc 载入平时的 zsh 配置。make setup 执行 uv sync --frozen, 按已提交的锁文件准备 .venv/,不重新解析锁文件。第 0 课没有第三方依赖。 如果机器没有 Python 3.12,uv 可能先下载解释器。
如果提示找不到 uv,先按照 uv 官方安装说明 安装, 重新载入终端环境后再运行。依赖安装失败属于环境问题,不是课程练习的红灯。
3. 随机数为什么可以重复
训练模型时,参数初始值和数据顺序经常包含随机选择。 计算机常用的伪随机数生成器按内部状态依次计算数值。 **种子(seed)**用于初始化状态;相同实现、相同初始状态和相同调用顺序,可以产生相同序列。
每抽取一次,生成器的内部状态就会向前推进。继续使用同一个生成器,不会自动回到初始状态。 数值本身仍可能碰巧重复,因此不能把“必须出现不同数字”当作随机性检查。
本课实验的核心代码如下。先阅读,不执行:
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. 运行一个贯穿实验
make check-tools这个命令依次运行两步:
- 环境检查输出操作系统、架构、Python 版本、解释器和虚拟环境路径,并检查基础工具能否找到。
- 示范实验输出种子、三组样本和首两组是否相同。
成功时有 ENV: OK 和 REPRO: OK 两个标记,命令退出码为 0。 这些标记由课程脚本打印,分别表示当前环境符合要求、本次随机实验满足检查条件。
executable 应在当前仓库的 .venv/bin/ 下,environment 应指向当前仓库的 .venv。 解释器文件本身可能链接到 uv 管理的安装位置,这不妨碍它使用仓库虚拟环境。
把一次实际输出保留在笔记里,不需要逐字段抄写。随后再运行一次相同命令,观察三组样本是否复现。 每次都是新进程,程序会重新创建两个生成器;不要将它和同一进程里继续调用 first 混淆。
需要单独查看实验时,可以运行:
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成功,能从输出识别本仓库使用的解释器与虚拟环境。- 两次运行的实际结果已比较,并留下预测、证据与必要修订。
- 两个必答项有自己的解释,经导师审阅后再记录结课。
下一课从张量开始,把数据的数量、形状和批量计算对应起来。
配套阅读
- Python 3.12:虚拟环境与包:理解环境隔离。
- Python 3.12:列表推导式:读懂本课抽样代码。
- Python 3.12:random:查看独立生成器和随机状态的说明。
- uv:运行项目命令:理解
uv run和项目环境的关系。