Перейти к содержимому
Ступень 00.1 Рабочее окружение

Python, виртуальные окружения и Jupyter

Ставим Python на компьютер, заводим для курса отдельную «коробку» с библиотеками (виртуальное окружение), запускаем Jupyter и VS Code и на простой арифметике прикидываем, когда понадобится видеокарта.

УРОКstage-0/0-1-environment/02-python-env.mdx1 ч 30 минУрок 2 из 3
После урока вы сможете
  • Установить Python 3.11+ и создать виртуальное окружение через venv или uv
  • Поставить зависимости курса из requirements.txt и проверить окружение скриптом
  • Запустить Jupyter Lab и подключить окружение к VS Code
  • Оценить стоимость обучения по правилу 6ND6ND, измерить производительность своей машины и объяснить, почему первые ступени идут на CPU

Python — язык почти всего ML. Но сам по себе Python умеет немного: силу ему дают библиотеки (их ещё называют пакетами) — готовые наборы чужого кода, которые подключают к своей программе. NumPy быстро считает с таблицами чисел, PyTorch обучает нейросети, matplotlib рисует графики. Библиотеки скачивают из интернета одной командой pip install имя (pip — программа-установщик, которая идёт вместе с Python).

У библиотек есть версии: авторы постоянно их обновляют, и в новой версии что-то может работать иначе. Отсюда проблема, которая рано или поздно ломает каждому вечер: конфликт версий. Одному проекту нужен PyTorch версии 2.4, другому — 2.8. Если ставить всё «в систему», один на весь компьютер, второй проект ломает первый, а через полгода вы уже не можете запустить собственный код.

Решение — виртуальное окружениевиртуальное окружениеEN virtual environment (venv)Отдельная папка со своим Python и своими библиотеками для одного проекта.: отдельная папка со своим Python и своими библиотеками на каждый проект. Как отдельная коробка с инструментами для каждой работы: что положили в одну, не мешает другой. В этом уроке мы поставим Python, создадим окружение для курса, запустим Jupyter и разберёмся с вопросом, который волнует всех: где взять видеокарту и когда она действительно понадобится.

Нужен Python 3.11 или 3.12. Курс проверяется на 3.11. Более новые версии обычно тоже работают, но поддержка свежего Python в PyTorch иногда появляется с задержкой. Проверьте, что уже стоит:

Окно терминала
python3 --version

Работайте внутри WSL (см. прошлый урок). В Ubuntu 24.04 уже есть Python 3.12, нужно доставить модуль venv:

Окно терминала
sudo apt update && sudo apt install python3-venv python3-pip

В Ubuntu 22.04 системный Python — 3.10. Поставьте новый через uv (ниже), это проще всего.

Окружение — это обычная папка (по традиции .venv) внутри проекта. В ней лежат ссылка на интерпретатор Python и своя папка site-packages, куда pip ставит библиотеки.

flowchart TB
SYS["Python 3.12 в системе"]
SYS --> A[".venv проекта ChinaAI<br/>numpy 2.x, torch, pytest"]
SYS --> B[".venv старого проекта<br/>numpy 1.x, torch 2.1"]
SYS --> C[".venv бота<br/>aiogram, httpx"]
Один Python — много независимых наборов библиотек

Активация — это не магия. Скрипт activate ставит папку .venv/bin в начало переменной PATH (помните её из прошлого урока?). После этого команды python и pip находятся сначала в окружении.

Окно терминала
cd ChinaAI
python3 -m venv .venv # создать окружение в папке .venv (-m: запустить модуль venv как программу)
source .venv/bin/activate # выполнить скрипт активации в текущем терминале (в Windows без WSL: .venv\Scripts\activate)
which python # → /home/ivan/ChinaAI/.venv/bin/python
python -c "import sys; print(sys.prefix != sys.base_prefix)" # -c: выполнить код из строки → True: мы в окружении
deactivate # выйти

После активации в начале строки терминала появляется (.venv). Активировать нужно в каждом новом окне терминала: окружение живёт в пределах сеанса.

менеджер пакетовменеджер пакетовEN package managerpip, uv, conda — устанавливают библиотеки вместе с их зависимостями. pip идёт вместе с Python. Ему есть современная замена — uv: он написан на Rust, ставит пакеты в разы быстрее и умеет сам скачивать нужную версию Python. Именно uv использует в своих заданиях Stanford CS336, один из лучших курсов по LLM.

Окно терминала
curl -LsSf https://astral.sh/uv/install.sh | sh # установка (macOS, Linux, WSL): curl скачивает скрипт, | sh сразу его выполняет
# или, если pip уже есть: pip install uv
uv venv --python 3.12 # создать .venv; скачает Python 3.12, если его нет
source .venv/bin/activate
uv pip install -r homework/requirements.txt # тот же интерфейс, что у pip
pip + venvuv
Где взятьидёт с Pythonставится одной командой
Скорость установкиобычнаяв разы быстрее
Ставит сам Pythonнетда: uv python install 3.12
Командыpython -m venv, pip installuv venv, uv pip install

Выбирайте любой вариант. Все команды курса пишутся для pip, и в uv они работают с префиксом uv.

Список библиотек проекта хранится в текстовом файле requirements.txt. В курсе он лежит в homework/requirements.txt:

numpy>=1.26
pytest>=8
pyyaml>=6
matplotlib>=3.8
torch>=2.4
# Табличный ML (модуль 2.4, ДЗ s2-hw02)
pandas>=2.2
scikit-learn>=1.4
lightgbm>=4.0

Строки, начинающиеся с #, — комментарии, pip их пропускает. Запись numpy>=1.26 значит «любая версия не ниже 1.26». Чтобы зафиксировать точные версии того, что стоит у вас сейчас, есть pip freeze > requirements.lock.txt. Так делают, когда важна полная воспроизводимость.

  1. Склонируйте курс и зайдите в папку: git clone https://github.com/samnolak/ChinaAI.git && cd ChinaAI.
  2. Создайте и активируйте окружение: python3 -m venv .venv && source .venv/bin/activate.
  3. Сначала поставьте PyTorch без CUDA. CUDACUDAEN CUDA (Compute Unified Device Architecture)Платформа NVIDIA для вычислений на видеокартах. В PyTorch видеокарта NVIDIA — это устройство "cuda" ("cuda:0", "cuda:1"…). — платформа NVIDIA, через которую PyTorch считает на видеокарте (урок 0.0.2). Сборка без неё весит в разы меньше полной, а на ступенях 0–3 GPU не нужен: pip install torch --index-url https://download.pytorch.org/whl/cpu.
  4. Остальное: pip install -r homework/requirements.txt. Уже стоящий torch pip не тронет.
  5. Jupyter: pip install jupyterlab ipykernel.
  6. Проверьте окружение скриптом из следующего раздела.

Дополнительный файл homework/requirements-llm.txt (transformers, datasets, peft, trl, accelerate) понадобится на ступенях 6–8. Ставить его сейчас не нужно.

Сохраните этот скрипт как check_env.py и запустите python check_env.py:

"""Проверка окружения курса ChinaAI: python check_env.py"""
import platform
import sys
# 1. Версия Python и путь к интерпретатору, который сейчас работает
print(f"Python {platform.python_version()} ({sys.executable})")
assert sys.version_info >= (3, 11), "Нужен Python 3.11 или новее"
# 2. Активно ли виртуальное окружение: внутри venv sys.prefix указывает на папку .venv
in_venv = sys.prefix != sys.base_prefix
print(f"venv {'да' if in_venv else 'НЕТ — активируйте окружение!'}")
# 3. NumPy — если не установлен, здесь будет ModuleNotFoundError
import numpy as np
print(f"NumPy {np.__version__}")
# 4. PyTorch и устройство: cuda (NVIDIA), mps (Mac на Apple Silicon) или cpu
try:
import torch
cuda = torch.cuda.is_available()
mps = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available()
device = "cuda" if cuda else "mps" if mps else "cpu"
print(f"PyTorch {torch.__version__} устройство: {device}")
x = torch.randn(256, 256, device=device) # случайная матрица 256×256 на этом устройстве
print(f"тест (x @ x.T).shape = {tuple((x @ x.T).shape)}")
except ImportError:
print("PyTorch не установлен — до ступени 3 он не нужен")

Вывод на машине автора (версии и пути у вас будут свои):

Python 3.11.15 (/home/user/.venvs/cai/bin/python)
venv да
NumPy 2.4.6
PyTorch 2.14.1+cu130 устройство: cpu
тест (x @ x.T).shape = (256, 256)

Суффикс версии подсказывает, какая это сборка: +cpu — без CUDA, +cu130 — с CUDA 13.0. У автора стоит CUDA-сборка, но видеокарты в машине нет, поэтому устройство — cpu. На вашей машине с CUDA-сборкой будет cuda. Устройство mps означает GPU в Mac на Apple Silicon.

Если что-то пошло не так, сверьтесь с таблицей. Почти все ошибки на этом шаге — из-за того, что окружение не активировано:

Что видитеПочемуЧто делать
python: command not foundв системе есть только python3пишите python3. Внутри активированного .venv работает и python
ensurepip is not available при создании venvв Ubuntu не установлен модуль venvsudo apt install python3-venv и создайте окружение заново
ModuleNotFoundError: No module named 'numpy'окружение не активировано или пакет не установленsource .venv/bin/activate, затем pip install -r homework/requirements.txt
error: externally-managed-environmentpip пытается ставить пакет в системный Pythonактивируйте .venv и повторите
в Jupyter ModuleNotFoundError, хотя в терминале всё работаетноутбук работает в другом ядревыберите ядро «Python (ChinaAI)» (см. ниже) или выполните в ячейке %pip install …

Jupyter Lab: код, текст и графики в одном документе

Заголовок раздела «Jupyter Lab: код, текст и графики в одном документе»

Jupyter-ноутбукJupyter-ноутбукEN Jupyter notebookДокумент из ячеек с кодом, текстом и графиками (.ipynb). Состояние живёт в ядре, пока оно запущено. состоит из ячеек. В ячейке может быть код или текст, а под ячейкой с кодом сразу появляется результат: число, таблица, график. Для исследования данных и экспериментов это удобнее скрипта.

Окно терминала
jupyter lab # откроется браузер с адресом вида http://localhost:8888/lab?token=...

Если Jupyter стоит не в окружении курса, зарегистрируйте окружение как отдельное ядро (kernel):

Окно терминала
python -m ipykernel install --user --name chinaai --display-name "Python (ChinaAI)"

Теперь в Jupyter можно выбрать ядро «Python (ChinaAI)».

Главное, что нужно знать:

  • Shift+Enter выполняет ячейку и переходит к следующей.
  • Ядро — это работающий процесс Python. Переменные живут в нём, пока его не перезапустят.
  • %timeit выражение замеряет время, %pip install пакет ставит пакет именно в окружение ядра. Не путайте с !pip: восклицательный знак запускает pip из системного PATH, и пакет может уйти не туда.

Для домашних работ (обычные .py файлы и тесты) удобнее редактор. Мы рекомендуем VS Code:

  1. Поставьте расширения Python и Jupyter от Microsoft, а в Windows ещё и WSL.
  2. Откройте папку ChinaAI (File → Open Folder, а из WSL просто code .).
  3. Ctrl+Shift+P → «Python: Select Interpreter» → выберите .venv. Встроенный терминал VS Code будет активировать окружение сам.
  4. Файлы .ipynb открываются прямо в VS Code, отдельный Jupyter Lab не обязателен.

графический процессорграфический процессор (GPU, видеокарта)EN graphics processing unit (GPU)Тысячи простых вычислительных ядер. Идеально подходит для матричных умножений, поэтому на GPU обучают нейросети. — это тысячи простых ядер, которые параллельно перемножают матрицы. Нейросеть — это почти сплошь матричные умножения, поэтому разница огромная. Процессор 4-ядерной машины, на которой писался курс, на умножении больших матриц в NumPy показал 80–160 GFLOPS (миллиардов операций с плавающей точкой в секунду), то есть около 0.1 TFLOPS (T — тера, триллион: 1 TFLOPS = 1000 GFLOPS). Одна игровая видеокарта последних поколений выдаёт по паспорту десятки TFLOPS: разница в сотни раз.

У вас 4× RTX 4080 по 32 ГБ и 48-ядерный EPYC — весь курс можно пройти без облаков. Подробная настройка драйвера, сборки PyTorch с CUDA и проверка связи между картами — на странице «Ваша лаборатория (4×GPU)». Сейчас, на ступени 0, достаточно убедиться, что карты видны:

Окно терминала
nvidia-smi # таблица: 4 видеокарты, объём памяти каждой, загрузка и температура
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.device_count())"

Ожидаемый вывод второй команды — True 4. Если видите False 0, у вас CPU-сборка PyTorch (как в шагах выше) или не установлен драйвер NVIDIA (тогда и nvidia-smi не сработает). CPU-сборка — это нормально до ступени 4. Сборку с CUDA можно поставить сразу или позже, по инструкции на странице лаборатории.

Узнайте, сколько реально выдаёт ваше железо. Сохраните скрипт как bench_flops.py и запустите:

"""Сколько GFLOPS выдаёт ваша машина на умножении матриц: python bench_flops.py"""
import time
import numpy as np
n = 2048
flop = 2 * n**3 # умножение n×n на n×n: n³ умножений и столько же сложений
A = np.random.default_rng(0).standard_normal((n, n), dtype=np.float32)
A @ A # прогрев: первый запуск всегда медленнее
t0 = time.perf_counter()
for _ in range(5):
A @ A
dt = (time.perf_counter() - t0) / 5 # среднее время одного умножения, секунды
print(f"CPU (NumPy, float32): {flop / dt / 1e9:8.0f} GFLOPS")
try:
import torch
if torch.cuda.is_available():
for i in range(torch.cuda.device_count()): # по очереди каждая видеокарта
X = torch.randn(8192, 8192, device=f"cuda:{i}", dtype=torch.bfloat16)
X @ X # прогрев
torch.cuda.synchronize(i) # дождаться, пока GPU закончит
t0 = time.perf_counter()
for _ in range(20):
X @ X
torch.cuda.synchronize(i)
dt = (time.perf_counter() - t0) / 20
print(f"GPU {i} ({torch.cuda.get_device_name(i)}, bf16): {2 * 8192**3 / dt / 1e12:6.1f} TFLOPS")
else:
print("GPU с CUDA не найден")
except ImportError:
print("PyTorch не установлен")

На машине автора (4 ядра, без видеокарты):

CPU (NumPy, float32): 122 GFLOPS
GPU с CUDA не найден

У вас цифры будут намного больше: и для процессора, и тем более для каждой видеокарты. Запишите свои цифры в журнал (папка journal/ в репозитории курса): ниже они понадобятся для расчёта, а на ступени 5 — для сравнения с дата-центровыми GPU. Команда torch.cuda.synchronize нужна потому, что GPU работает асинхронно: Python отдаёт ему задание и сразу идёт дальше, а без синхронизации вы измерили бы время отправки команды, а не вычисления.

Варианты для тех, кто учится из России (например, в поездке или на другом компьютере):

ВариантПлюсыМинусы
Mac на Apple SiliconPyTorch работает через mpsНе всё из экосистемы CUDA доступно
Yandex DataSphereНоутбуки с GPU, оплата в рубляхПлатно, следите за временем работы
Российские GPU-облака (Selectel, Cloud.ru и др.)Почасовая аренда сервера с GPUНужно уметь работать в терминале — вы уже умеете
Kaggle NotebooksБесплатная квота GPU (на момент написания около 30 часов в неделю)Для GPU нужно подтвердить номер телефона. С российскими номерами бывают проблемы
Google ColabБесплатный GPU T4Лимиты плавают, платный план российской картой не оплатить, бывают сложности с регистрацией

Сколько вычислений нужно на обучение? Есть грубое, но удивительно точное правило (подробно — в уроке 5.1.1 о законах масштабирования):

C≈6⋅N⋅D FLOP.C \approx 6 \cdot N \cdot D \ \text{FLOP}.

Словами: число операций ≈ 6 × число параметров модели × число токенов, на которых она учится. Здесь CC — сколько операций нужно (FLOP — одна операция с дробными числами: умножение или сложение), NN — сколько чисел-весов в модели (параметров, урок 0.0.1), DD — сколько токенов (или примеров) она «прочитает» за обучение. Множитель 6 складывается так: примерно 2 операции на параметр, когда модель считает ответ (умножить и сложить), и ещё около 4, когда она вычисляет, куда подкрутить веса. Как устроены эти два этапа, вы узнаете на ступенях 1 и 3, а пока достаточно запомнить множитель 6.

Нам понадобится научная запись из урока 0.0.2: 10610^6 — единица с шестью нулями (миллион), 10710^7 — десять миллионов. При умножении таких чисел показатели степени складываются: 106⋅107=106+7=101310^6 \cdot 10^7 = 10^{6+7} = 10^{13}, а при делении — вычитаются: 1013/1010=103=100010^{13} / 10^{10} = 10^{3} = 1000.

Пример: модель на миллион параметров (N=106N = 10^6) читает 10 миллионов токенов (D=107D = 10^7): C=6⋅106⋅107=6⋅1013C = 6 \cdot 10^6 \cdot 10^7 = 6 \cdot 10^{13} операций. При 50 GFLOPS (5⋅10105 \cdot 10^{10} операций в секунду) это 6⋅10135⋅1010=65⋅103=1200\frac{6 \cdot 10^{13}}{5 \cdot 10^{10}} = \frac{6}{5} \cdot 10^{3} = 1200 секунд, то есть 20 минут. Так же посчитаем остальные задания курса:

СтупеньМодельNNDDC=6NDC = 6NDCPU, 50 GFLOPS1 GPU, ~40 TFLOPS
2логистическая регрессия10410^410610^66⋅10106 \cdot 10^{10}~1 секундамгновенно
3MLP10510^510710^76⋅10126 \cdot 10^{12}~2 минутыдоли секунды
4мини-GPT10610^610710^76⋅10136 \cdot 10^{13}~20 минутсекунды
4, GPU-трекGPT на русском корпусе3⋅1073 \cdot 10^710910^91.8⋅10171.8 \cdot 10^{17}~40 дней~1.3 часа
5MiniMind-подобная LLM6.4⋅1076.4 \cdot 10^710910^93.8⋅10173.8 \cdot 10^{17}~90 дней~2.7 часа

Названия моделей в таблице пока просто имена: что такое логистическая регрессия, MLP и MiniMind, вы узнаете на этих ступенях. Сейчас важна только арифметика: NN и DD подставляем в 6ND6ND и делим на скорость машины. Последние две строки — условные примеры (миллиард токенов обучения). 40 TFLOPS — условная реальная производительность одной современной видеокарты в bf16 (осторожная оценка); подставьте свои цифры из bench_flops.py. Оценка для ступени 5 по порядку величины согласуется с заявлением авторов MiniMind: модель на 64M параметров обучается примерно за 2 часа на одной RTX 3090. На четырёх картах в идеале было бы вчетверо быстрее, но обмен данными между картами по PCIe съест часть выигрыша. Об этом — в уроке 5.4.3.

Две оговорки. Маленькие модели не загружают GPU полностью, поэтому на ступенях 2–4 реальный выигрыш от видеокарты меньше, чем в таблице. А CPU-столбец посчитан для обычного ноутбука: ваш 48-ядерный EPYC быстрее.

Вывод: ступени 0–3 (Python, математика, micrograd, PyTorch) рассчитаны на CPU. Тесты всех домашних работ тоже выполняются на процессоре, а тяжёлое обучение со ступени 5 проверяется по сохранённым метрикам. Со ступени 4 у вас появляется GPU-трек с моделями в десятки раз больше. На ступенях 5 (претрейн мини-LLM) и 6 (LoRA, GRPO) базовый путь по-прежнему проходится на CPU, но только на крошечных конфигурациях: настоящие эксперименты там требуют видеокарт.

  1. Поставьте Python 3.11+ и создайте окружение .venv в папке курса (через venv или uv).
  2. Поставьте зависимости (CPU-сборка torch, затем homework/requirements.txt, затем jupyterlab ipykernel).
  3. Запустите check_env.py и убедитесь, что в строке venv написано «да».
  4. Откройте Jupyter Lab, создайте ноутбук и сравните в двух ячейках скорость Python и NumPy. Понимать каждую строку пока не нужно — Python начнётся в модуле 0.2, NumPy — в модуле 0.3. Сейчас важно увидеть разницу во времени:
    import numpy as np # подключить библиотеку NumPy под коротким именем np
    data = [float(i) for i in range(1_000_000)] # обычный список Python из миллиона чисел 0.0, 1.0, 2.0, …
    x = np.arange(1_000_000, dtype=np.float64) # те же числа, но в массиве NumPy
    %timeit sum(v * v for v in data) # сумма квадратов циклом Python — замер времени
    %timeit x @ x # та же сумма квадратов одной операцией NumPy
    У автора первая строка заняла около 35 мс, вторая — доли миллисекунды (точные цифры зависят от машины и её загрузки). Почему NumPy быстрее в десятки и сотни раз, разберём в модуле 0.3.
  5. Сделайте Restart Kernel and Run All и убедитесь, что ноутбук выполняется сверху вниз без ошибок.
  6. Откройте папку курса в VS Code и выберите интерпретатор .venv.
Проверь себя5 вопросов
1 Вы открыли новое окно терминала и сразу выполнили pip install numpy в папке курса. Что произошло?
2 Какие признаки говорят, что окружение активно?Можно выбрать несколько ответов
3 Модель на 2 млн параметров (2⋅1062 \cdot 10^6) учится на 50 млн токенов (5⋅1075 \cdot 10^7). Компьютер стабильно выдаёт 100 GFLOPS (101110^{11} операций в секунду). Сколько минут займёт обучение по правилу 6ND6ND?
4 Ноутбук Jupyter выдал отличный результат. Что сделать, прежде чем ему доверять?
5 Зачем в курсе ставят PyTorch командой с --index-url https://download.pytorch.org/whl/cpu?
  • Python 3.11–3.12, каждому проекту — своё окружение .venv. Системный Python не трогаем, sudo pip не используем.
  • Активация ставит .venv/bin в начало PATH. В каждом новом терминале окружение нужно активировать снова.
  • uv — быстрая замена pip с тем же интерфейсом, умеет сам скачивать Python.
  • Jupyter удобен для экспериментов, но перед выводами делайте Restart & Run All.
  • Обучение стоит ≈6ND\approx 6ND FLOP. На первых ступенях это минуты на CPU. Со ступени 4 пригодятся ваши 4 видеокарты, без них — облако, DataSphere или Kaggle.

Дальше: как устроены домашние задания и автопроверка — и первое задание прямо в браузере.