00_check_env.ipynb 说明文档

这份文档是给第一次接触 Python、Jupyter notebook、AutoDL 和大模型实验的同学准备的。

这个 notebook 的任务非常朴素:

你可以把它理解成:

如果这一步没有通过,后面的 LoRA 微调 notebook 往往也会出问题。


一、这个 notebook 总共在检查什么

它主要检查 4 件事:

  1. 你现在到底在什么 Python 环境里
  2. 这台 AutoDL 实例有没有 GPU
  3. torch 能不能识别 CUDA
  4. 后面课程要用的几个核心 Python 包能不能导入

二、Cell 0:开场说明

# 00_check_env

这个 notebook 用于检查 AutoDL 上的基本环境是否正常。建议第一次进入实例后先完整运行一遍。

这一格只是说明文字,没有代码。

它在提醒你:


三、Cell 1:检查 Python、当前目录和文件

代码:

import os, sys

print("Python:", sys.version)
print("Current working directory:", os.getcwd())
print("Files in current directory:")
print(os.listdir("."))

这一格在做什么

它做了 3 件事:

  1. 看你现在运行的是哪个 Python
  2. 看你当前站在哪个目录里
  3. 看这个目录下有哪些文件

这是最基础的一步,但非常重要。很多实验出错,根本原因不是模型坏了,而是:

逐行解释

import os, sys

这里导入了两个 Python 标准库:

print("Python:", sys.version)

这一行会打印当前 Python 的详细版本信息。

这里的重点不是背 sys.version,而是知道:

你通常会看到类似:

Python: 3.10.14 ...

这告诉你:

print("Current working directory:", os.getcwd())

getcwd() 的全称是:

意思是:

如果它输出的是:

/root/course_lora

说明你当前 notebook 的执行位置就在课程目录里。

这很重要,因为很多相对路径,比如:

都默认是从“当前目录”出发去找的。

print("Files in current directory:")

这只是打印一行提示文字,让后面的输出更好读。

print(os.listdir("."))

listdir() 的意思是:

这里传进去的是 "."

在命令行和 Python 里:

所以这一行的意思就是:

你应该能看到类似:

如果这些文件不在,通常说明:

这一格跑完后你应该确认什么

  1. Python 版本正常
  2. 当前目录是你预期的课程目录
  3. 课程文件确实存在

四、Cell 2:检查 GPU 是否存在

代码:

import subprocess

print("=== nvidia-smi ===")
result = subprocess.run(["nvidia-smi"], capture_output=True, text=True)
print(result.stdout if result.stdout else result.stderr)

这一格在做什么

这格不是在用 Python 检查 GPU,而是在让 Python 帮你执行一个系统命令:

这个命令几乎是 NVIDIA GPU 环境检查的第一步。

如果这一格输出正常,通常说明:

逐行解释

import subprocess

subprocess 是 Python 标准库,用来:

比如你在 Terminal 里会输入:

nvidia-smi

那在 Python 里,就可以通过 subprocess 来做同样的事。

只是打印一个小标题,让输出更清楚。

result = subprocess.run(["nvidia-smi"], capture_output=True, text=True)

这是这一格最核心的一行。

先看主函数:

这里传进去的是:

为什么是列表?

因为 subprocess.run() 常常把命令和参数拆成列表形式传入。
如果命令更复杂,可能会写成:

["python", "train_lora.py", "--train_file", "data/sample_train.json"]

这里的两个参数也很重要:

capture_output=True

意思是:

这样我们后面才能通过 result.stdoutresult.stderr 把结果打印出来。

text=True

意思是:

如果没有这一项,输出可能会是 bytes,读起来不方便。

print(result.stdout if result.stdout else result.stderr)

这里用了一个 Python 的简写表达式:

A if 条件 else B

意思是:

为什么这样写?

因为:

所以这行的逻辑很实用:

正常情况下你会看到什么

通常会看到一大段 NVIDIA 表格,里面包括:

如果失败会说明什么

如果这里报错,常见原因是:

如果这一格不过,后面的训练一般也不用继续了。


五、Cell 3:检查 torch 和 CUDA

代码:

import torch

print("torch version:", torch.__version__)
print("cuda available:", torch.cuda.is_available())
if torch.cuda.is_available():
    print("device:", torch.cuda.get_device_name(0))
    print("device count:", torch.cuda.device_count())

这一格在做什么

上一格检查的是:

这一格检查的是:

这两件事不是一回事。
有时候 nvidia-smi 正常,但 torch.cuda.is_available() 还是 False

逐行解释

import torch

导入 PyTorch。

如果这一行就报错:

那说明当前环境里 PyTorch 还没装好。

print("torch version:", torch.__version__)

打印 PyTorch 版本。

__version__ 是很多 Python 包都会提供的版本信息属性。

你会知道:

print("cuda available:", torch.cuda.is_available())

这是 PyTorch 检查 GPU 最常用的一行。

torch.cuda.is_available() 的意思是:

返回值是布尔值:

如果是 True,说明:

如果是 False,说明:

if torch.cuda.is_available():

这是一句条件判断:

这样写是为了避免在没有 GPU 的时候继续执行下面的语句,导致出错。

print("device:", torch.cuda.get_device_name(0))

这里是在问:

参数 0 的意思是:

因为 Python 和大多数程序都从 0 开始编号。

如果你的实例只有 1 块卡,0 就是唯一那块卡。

print("device count:", torch.cuda.device_count())

这行打印 GPU 的数量。

如果返回:

这一格的意义

这一格跑通,才表示:

对于后面的 LoRA 微调,这一格比上一格更关键。


六、Cell 4:检查核心依赖包

代码:

required = ["transformers", "datasets", "peft", "accelerate"]
for pkg in required:
    try:
        __import__(pkg)
        print(f"[OK] {pkg}")
    except Exception as e:
        print(f"[FAIL] {pkg}: {e}")

这一格在做什么

它在检查后续课程实验最核心的 4 个包能不能导入:

这比简单地看 pip list 更有用,因为:

逐行解释

required = ["transformers", "datasets", "peft", "accelerate"]

这里定义了一个列表 required,表示:

为什么是这 4 个?

因为这套课程最小 LoRA 实验里,它们分别承担:

for pkg in required:

这是一个循环。

意思是:

try:

进入“尝试执行”的代码块。

如果这里面的代码报错,就跳到 except

__import__(pkg)

这是 Python 的一个内置函数。
它的作用和:

import transformers

有点像,但更灵活,因为它允许你把包名放在变量里。

比如当:

时,这行就相当于:

import transformers

下一轮如果:

它就相当于:

import datasets

print(f"[OK] {pkg}")

如果导入成功,就打印:

[OK] transformers

这里用了 f-string,也就是格式化字符串:

f"...{变量}..."

意思是把变量值直接插进字符串。

except Exception as e:

如果导入失败,Python 会进入这里。

Exception as e 的意思是:

print(f"[FAIL] {pkg}: {e}")

如果某个包导入失败,就打印失败信息和错误原因。

比如可能出现:

[FAIL] peft: No module named 'peft'

这一格的意义

如果这一格全部 [OK],说明:

如果某一项 [FAIL],就要先解决依赖问题,再继续。


七、Cell 5:空白代码格

这一格是空的。

它没有任何作用,可以理解成:

对实验没有影响。


八、Cell 6:环境检查阶段结束说明

如果上面各项都正常,那么说明这台实例已经基本适合继续做 LoRA 课程实验。

这句话的意思很重要:

不是说后面一定 100% 没问题,而是说:


九、这个 notebook 跑完以后,你应该得到什么结论

如果 00_check_env.ipynb 跑通了,你至少应该能回答下面这些问题:

  1. 我当前用的是哪个 Python?
  2. 我当前是不是在课程目录里?
  3. 这台机器有 GPU 吗?
  4. PyTorch 能识别 GPU 吗?
  5. transformers / datasets / peft / accelerate 能导入吗?

如果这些问题都能回答“可以”,那你就可以进入下一步:


十、这一份 notebook 最值得你学会的,不只是命令

真正重要的是这种实验习惯:

  1. 先检查环境
  2. 再检查依赖
  3. 最后才开始训练

这是大模型实验里很重要的工程习惯。
以后不只是 AutoDL,在任何服务器、任何实验平台上,这个顺序都能帮你少踩很多坑。