系列说明:本系列根据开源课程「AI Engineering From Scratch」整理。从零开始,系统性地走完一名 AI 工程师需要的全部基础。
版本控制这件事,我以前觉得多余
说个真实的经历。
刚开始写代码那几年,我一直觉得 Git 是"有点烦"的东西。一个 Python 脚本改来改去,改坏了就 Ctrl+Z,再不行就从头写。反正又不是什么大项目,记什么版本啊。
后来有一次,我在跑一个分类模型,调了两天终于把准确率从 72% 推到了 81%。然后我想继续优化,改了几个地方,结果……准确率掉到了 63%。
我想回到 81% 的那个版本。发现回不去了。
那份代码改了多少处,我已经不记得了。
那天晚上我装好了 Git,从此没有动摇过。
Git 是在干什么
用一句话说:Git 是给你的代码拍快照的工具。
每次你 commit,就是告诉 Git:"记住现在这个状态。" 以后不管你怎么改,都能回到这个时间点。
更进一步理解,Git 管理的是三个区域之间的流动:
工作区(你正在编辑的文件) ↓ git add暂存区(准备好要记录的改动) ↓ git commit本地仓库(已经记录下来的快照) ↓ git push远程仓库(GitHub 上的备份)
有人问我暂存区(Staging Area)存在的意义是什么——直接 commit 不就好了?
原因是:你可能改了十个文件,但只想把其中三个相关的改动记录成一个 commit。暂存区让你有机会"精选"要提交的内容,而不是把一堆乱七八糟的修改混在一起。
每天都会用到的五个命令
第一步:告诉 Git 你是谁
# 全局设置,只需要做一次git config --global user.name "你的名字"git config --global user.email "你的邮箱"
这一步很多人会忘,结果 commit 历史里出现奇怪的作者名。
第二步:日常工作流
# 查看当前状态:哪些文件改过了,哪些还没暂存git status# 把某个文件加入暂存区git add train.py# 或者一次把所有改动都暂存git add .# 记录一个快照,写清楚这次改了什么git commit -m "把学习率从 0.01 调整为 0.001,验证集准确率提升3%"# 推送到 GitHubgit push origin main
commit message 写什么很重要。"修改了一些东西"这种完全没用。好的 commit message 是:一句话说清楚改了什么、为什么改。三个月后你翻历史,会感谢现在认真写 message 的自己。
第三步:用分支做实验
这是我觉得 Git 最有价值的功能之一。
你想试一个新的优化器,但不确定能不能跑通,又怕把现在好好的 main 分支搞坏。这时候就建一个新分支:
# 建一个叫 experiment/adam-optimizer 的分支,并切换过去git checkout -b experiment/adam-optimizer# 在这个分支上随便改,不影响 main# 改完觉得好,合并回去git checkout maingit merge experiment/adam-optimizer# 觉得不好,直接扔掉这个分支就行git branch -d experiment/adam-optimizer
分支是"不破坏现有代码的前提下,大胆尝试"的工具。AI 实验天天要试新东西,这个习惯非常值得养。
第四步:把课程仓库拉下来
# 克隆课程仓库git clone https://github.com/rohitg00/ai-engineering-from-scratch.gitcd ai-engineering-from-scratch# 建自己的分支,在上面记录学习进度git checkout -b my-progress# 做完某个练习,提交一下git add .git commit -m "完成 Phase 0 Lesson 02 练习"git push origin my-progress
第五步:查看历史
# 看提交历史,--oneline 让每条记录只显示一行git log --oneline# 输出大概长这样:# a3f2c1d 把学习率从 0.01 调整为 0.001# b7e9812 完成数据预处理脚本# c4d1a09 初始化项目结构
.gitignore:有些东西不应该被追踪
模型文件动辄几百 MB,训练产生的 checkpoint 更是巨大。这些东西不该放进 Git 仓库里,否则你的仓库会越来越重,push 会越来越慢。
在项目根目录创建一个 .gitignore 文件:
# 模型检查点文件(体积大,不适合用 Git 追踪)*.pt*.pth*.safetensors*.ckpt# 训练输出目录outputs/checkpoints/runs/# Python 产生的缓存文件__pycache__/*.pyc*.pyo.ipynb_checkpoints/# 数据集(通常很大,单独管理)data/raw/*.csv*.parquet# 环境配置(包含密钥,绝对不能提交).env*.env.local# 编辑器杂项.DS_Store.vscode/settings.json
.env 文件里通常存放 API Key 之类的敏感信息,一定要加进 .gitignore,不然可能会不小心把密钥推送到公开仓库里。这种事情每年都在发生,有人因此被盗用了几万美元的云服务费。 一张表:你现在只需要这些
原课给了一张很实用的命令速查表,我搬过来:
git clone | |
git addgit commit | |
git push | |
git checkout -b | |
git log --oneline |
rebase、cherry-pick、submodule 这些先不用管。用到的时候再学,现在会这五个就够了。
几个容易混淆的概念
有几个词刚接触时经常搞混,统一说清楚:
Commit 和 Save 的区别:普通的 Save 只保存当前文件状态,Commit 是给整个项目打一个带时间戳的快照,可以随时回退到任何一个 commit 的状态。 Branch(分支)不是"复制了一份代码":分支只是一个指向某个 commit 的指针。创建分支几乎没有开销,所以不用担心"建太多分支会不会很重"。 Merge(合并)是在做什么:把一个分支上的改动,应用到另一个分支上。大多数时候 Git 能自动完成,只有两个分支都改了同一行代码时才会出现冲突,需要手动解决。 Remote(远端)就是 GitHub:你的 local repo 是在自己电脑上的,remote 是存在 GitHub 服务器上的备份。push 是把本地的改动同步到远端,pull 是把远端的更新拉回本地。本课小结
Git 不是什么高深的东西,但它是所有工程工作的基础设施。你在这个系列里写的每一行代码,都应该用 Git 管理起来。
三个核心习惯:
写完一个小功能就 commit,不要等"写好了"再提交。小步提交更容易定位问题。 实验开新分支,不要在 main 上直接乱改。分支便宜,用起来。 commit message 写人话,让三个月后的自己能看懂在做什么。下一篇预告
Phase 0-03:GPU 配置与云服务——CPU 跑训练,你会等到崩溃。下一篇我们聊聊怎么用本地 GPU、Google Colab 以及租云 GPU,以及一个简单的 CPU vs GPU 性能对比实验,数字会让你很直观地感受到差距有多大。
系列导航
← 上一篇:Phase 0-01·课程介绍与环境准备
→ 下一篇:Phase 0-03·GPU 配置与云服务
AI 的世界每天都比昨天更陌生一点,但也更有意思一点。我们明天见。
夜雨聆风