Перейти до вмісту

Відтворювані середовища Python, CUDA та ROCm

Трек «Інженерія ШІ/МН» | Складність: [MEDIUM] | Час: 2-3 години

Передумови: Модуль 1.1: Передумови та налаштування середовища, Модуль 1.2: Основи домашньої ШІ-станції, базова навігація в командному рядку та впевненість у редагуванні невеликих текстових файлів.

Результати навчання

Розділ «Результати навчання»
  • Спроєктувати локальне для проєкту середовище Python, яке інший учень зможе відтворити без вашої історії оболонки чи глобального стану пакетів.
  • Діагностувати збої середовища, розділяючи проблеми інтерпретатора Python, розв’язання пакетів, драйвера GPU і сумісності середовища виконання фреймворку.
  • Порівняти звичайні віртуальні середовища, менеджери вищого рівня та контейнери, а тоді обґрунтувати, що пасує навчальному проєкту, командній робочій станції чи прототипу, прив’язаному до розгортання.
  • Оцінити, чи CUDA або ROCm внутрішньо сумісні, перш ніж встановлювати фреймворк глибокого навчання, замість виявляти несумісність через помилки під час виконання.
  • Побудувати й запустити димовий тест, який доводить, що середовище імпортує очікувані пакети, використовує очікуваний інтерпретатор і бачить задуманий бекенд CPU, CUDA або ROCm.

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

(Міра — гіпотетичний ілюстративний учень, не задокументований інцидент.) У понеділок Міра приєднується до невеликої команди прикладного ШІ й отримує репозиторій моделі, короткий README і повідомлення: «Має запуститися після встановлення requirements». До вівторка один колега може навчати на NVIDIA GPU, інший тихо перемикається на CPU, а ноутбук Міри імпортує іншу версію пакета, ніж скрипт командного рядка. Код моделі ніхто не змінював, але кожна людина бачить іншу систему.

Це не задача з дрібниць Python. Це системна проблема, замаскована під складнощі налаштування. Проєкти ШІ поєднують інтерпретований код, компільовані нативні розширення, драйвери обладнання, середовища виконання обчислень і wheel-пакети фреймворків, зібрані під конкретні припущення. Коли ці припущення розходяться, учень часто звинувачує рядок коду моделі, який видно, хоча збій виник кількома шарами нижче.

Відтворюваність — це навичка, яка перетворює цей хаос на систему, яку можна перевірити. Відтворюване середовище не означає, що кожен лептоп однаковий, і не означає, що більше ніколи не доведеться налагоджувати налаштування. Воно означає, що проєкт має задекларований шлях, ізольований інтерпретатор, запис залежностей, припущення про обладнання і коротку послідовність перевірок, яка показує, де стек здоровий, а де зламаний.

Старші практики дбають про це, бо невідтворювані середовища марнують дорогий час обладнання і ускладнюють пояснення інцидентів. Початківцям варто дбати, бо кожен наступний модуль треку «Інженерія ШІ/МН» припускає, що команда Python, ядро ноутбука й імпорт фреймворку означають те, на що схожі. Якщо середовищу не можна довіряти, не можна довіряти й експерименту.

Ментальна модель: відтворюваність — це проблема меж

Розділ «Ментальна модель: відтворюваність — це проблема меж»

Локальне середовище ШІ — це не одна річ. Це стек меж, і кожна межа відповідає на інше питання. Операційна система відповідає, чи машина може завантажити драйвери й бібліотеки. Драйвер GPU відповідає, чи обладнання видиме. CUDA або ROCm відповідає, чи програмне забезпечення може просити GPU виконувати обчислення. Python і фреймворк відповідають, чи ваш код може викликати правильні компільовані бінарники.

Найболючіші сесії налаштування починаються, коли учень ставиться до цих меж як до взаємозамінних. Переустановлюють Python, коли немає драйвера, оновлюють драйвер GPU, коли ядро ноутбука вказує на чуже віртуальне середовище, або встановлюють wheel-пакет фреймворку лише для CPU і потім дивуються, чому GPU невидимий. Виправлення — не запам’ятати всі можливі комбінації версій; виправлення — навчитися питати, який шар володіє збоєм.

Стек проєкту ШІ, читайте знизу вгору
+--------------------------------------------------------------+
| Код проєкту та ноутбуки |
| model.py, train.py, ноутбуки, тести, файли конфігурації |
+--------------------------------------------------------------+
| Пакети Python і wheel-пакети фреймворків |
| numpy, torch, tensorflow, tokenizers, компільовані розширення|
+--------------------------------------------------------------+
| Інтерпретатор Python та ізольоване середовище |
| .venv/bin/python, метадані pip, прив’язка ядра ноутбука |
+--------------------------------------------------------------+
| Родина середовищ виконання обчислень |
| бібліотеки CUDA для NVIDIA, бібліотеки ROCm/HIP для AMD |
+--------------------------------------------------------------+
| Драйвер GPU і видимість пристрою |
| nvidia-smi, rocminfo, модулі ядра, дозволи пристрою |
+--------------------------------------------------------------+
| Операційна система, ядро, файлова система, оболонка |
| дистрибутив Linux, менеджер пакетів, PATH, робочий каталог |
+--------------------------------------------------------------+

Важливий хід — налагоджувати вниз або вгору навмисно, а не навмання. Якщо пакет не імпортується, почніть із шару середовища Python і пакетів. Якщо пакет імпортується, але GPU недоступний, спустіться до збірки фреймворку, родини середовища виконання і видимості драйвера. Якщо інструмент драйвера не бачить пристрій, Python не перший підозрюваний.

Пауза і прогноз: Колега каже, що import torch працює, але torch.cuda.is_available() повертає False на робочій станції з NVIDIA GPU. Перш ніж читати далі, вирішіть, які два шари ви б оглянули першими і який шар не чіпали б, доки не матимете доказів.

Сильна перша відповідь — оглянути wheel-пакет фреймворку і шар драйвера/середовища виконання. Імпорт доводить лише, що Python знайшов пакет на ім’я torch; він не доводить, що пакет зібрано з підтримкою CUDA, що драйвер може показати GPU, або що бібліотеки середовища виконання, яких очікує wheel-пакет, придатні. Перестворення віртуального середовища зрештою може стати корисним, але перевстановлення самого Python зазвичай дорога здогадка.

Базове правило: один проєкт, одне середовище, один шлях перевірки

Розділ «Базове правило: один проєкт, одне середовище, один шлях перевірки»

Базове правило цього треку просте: один проєкт, одне ізольоване середовище, один задокументований шлях налаштування і один димовий тест. Правило звучить дрібно, але запобігає найпоширенішому збою ранньої роботи зі ШІ: багато проєктів повільно ділять один глобальний інтерпретатор, доки версії пакетів і ядра ноутбуків стають неможливими для аналізу.

Ізольоване середовище дає кожному проєкту приватний каталог пакетів і передбачуваний шлях інтерпретатора. Шлях інтерпретатора важливий, бо pip install і python train.py мають посилатися на те саме середовище. Якщо ні, ви отримуєте класичний збій, коли встановлення вдається в одному терміналі, а застосунок падає в іншому.

Задокументований шлях налаштування важливий, бо пам’ять — це не відтворюваність. Якщо єдиний запис середовища — «я щось встановив минулого місяця», проєкт не можна передати іншому учню, відтворити на другій робочій станції чи діагностувати після невдалого оновлення. Мета — не ідеальна корпоративна система збірки в перший день; мета — достатньо доказів, щоб майбутня людина могла відбудувати ту саму стартову точку.

Димовий тест важливий, бо успішні журнали встановлення — не доказ. Інсталятори пакетів можуть успішно встановити wheel-пакети лише для CPU, лишити ядро ноутбука прив’язаним до старого інтерпретатора або прийняти версії, які імпортуються, але падають під час реальної тензорної операції. Димовий тест дає проєкту відому контрольну точку до того, як у сюжет входить код моделі.

Звичайна форма відтворюваного проєкту
my-ai-project/
+-- .venv/ # локальний інтерпретатор проєкту та встановлені пакети
+-- src/ # код проєкту, який можна імпортувати
+-- notebooks/ # дослідження, прив’язане до середовища проєкту
+-- data/ # локальні зразки даних, зазвичай не комітять, якщо великі
+-- outputs/ # згенеровані артефакти, зазвичай ігнорує Git
+-- requirements.in # прямі залежності, обрані людиною
+-- requirements.txt # розв’язаний або зафіксований вхід встановлення для цього проєкту
+-- verify_env.py # димовий тест інтерпретатора, пакетів і бекенду
+-- README.md # кроки налаштування та перевірки
+-- .gitignore # виключає .venv, outputs, кеші, великі локальні файли

Ця структура навмисно звичайна. Звичайні середовища легше оглядати, документувати й замінювати, коли вони ламаються. Що менше таємниць у вашому налаштуванні, то більше уваги можна витратити на дані, поведінку навчання і якість моделі.

Навмисна побудова першого середовища

Розділ «Навмисна побудова першого середовища»

Перше середовище має бути достатньо нудним, щоб ви могли пояснити кожен рядок налаштування. Почніть зі створення каталогу проєкту, потім створіть віртуальне середовище всередині цього каталогу. Щойно віртуальне середовище існує, запускайте команди керування пакетами через .venv/bin/python -m pip, щоб інтерпретатор і інсталятор були зв’язані шляхом, а не припущеннями оболонки.

Terminal window
mkdir -p reproducible-ai-env/src reproducible-ai-env/notebooks reproducible-ai-env/data reproducible-ai-env/outputs
cd reproducible-ai-env
python3.12 -m venv .venv
.venv/bin/python -m pip install --upgrade pip setuptools wheel
.venv/bin/python -m pip --version
.venv/bin/python -c "import sys; print(sys.version); print(sys.prefix)"

Команда python3.12 -m venv .venv у цьому прикладі — єдиний неминучий крок bootstrap, бо середовища ще немає. Після цього модуль використовує .venv/bin/python явно, щоб встановлення пакетів, перевірка і скрипти йшли під інтерпретатором проєкту. У командному README зазначте, яку команду bootstrap використовує ваша операційна система, а решту робочого процесу лишайте з явним шляхом.

Початківець часто питає, чому активації недостатньо. Активація зручна для інтерактивної роботи, але змінює стан оболонки, а стан оболонки легко втратити між терміналами, ноутбуками, запускачами задач і інтеграціями редактора. Команди з явним шляхом галасливіші, проте роблять документацію й автоматизацію надійнішими, бо сама команда називає інтерпретатор.

Terminal window
cat > requirements.in <<'EOF'
numpy
packaging
EOF
.venv/bin/python -m pip install -r requirements.in
.venv/bin/python -m pip freeze > requirements.txt
.venv/bin/python -m pip check

Розділення requirements.in і requirements.txt — корисний місток від початківця до практика. Файл .in записує залежності, яких проєкт навмисно попросив, а файл .txt записує конкретний встановлений результат, включно з транзитними залежностями. Невеликі соло-проєкти іноді використовують лише requirements.txt, але більші проєкти виграють від знання, які залежності були прямим вибором, а які прийшли, бо їх вимагав інший пакет.

Terminal window
cat > .gitignore <<'EOF'
.venv/
__pycache__/
.ipynb_checkpoints/
outputs/
*.pyc
EOF
cat > README.md <<'EOF'
# Reproducible AI Environment
## Setup
Create the environment with Python 3.12, then run package commands through `.venv/bin/python`.
## Install
`.venv/bin/python -m pip install -r requirements.txt`
## Verify
`.venv/bin/python verify_env.py`
EOF

Цей README навмисно короткий, але вже фіксує контракт відтворюваності. Він каже наступній людині, який рядок Python має значення, як встановлюються пакети і як перевіряється здоров’я. Кращий README може пізніше додати очікування щодо GPU, але навіть ця мала версія набагато сильніша за недокументоване глобальне середовище.

Зупиніться і подумайте: Якщо колега каже «Я активував середовище вчора, тож редактор і сьогодні має його використовувати», яке приховане припущення він робить? Запишіть, як ви доведете, який інтерпретатор насправді використовує редактор або ноутбук.

Приховане припущення — що кожен інструмент ділить той самий стан активації оболонки. Редактори, сервери ноутбуків, запускачі задач і термінали часто стартують як окремі процеси, тож можуть не успадкувати активацію, яку ви вважаєте успадкованою. Доказ — надрукувати шлях інтерпретатора зсередини саме того інструмента, який запускає код, а не з іншого термінала, який лише виглядає схожим.

Опрацьований приклад: розбіжність ноутбука і CLI

Розділ «Опрацьований приклад: розбіжність ноутбука і CLI»

Розгляньмо проєкт, де димовий тест командного рядка працює, а ноутбук падає з ModuleNotFoundError: No module named 'numpy'. Слабка діагностика — «Jupyter зламаний». Краща діагностика — «ядро ноутбука, ймовірно, прив’язане до іншого інтерпретатора, ніж CLI проєкту».

Спочатку доведіть, що використовує командний рядок. Ця команда друкує шлях інтерпретатора й імпортує numpy зі середовища проєкту. Оскільки вона викликає .venv/bin/python напряму, немає двозначності, який інтерпретатор перевіряється.

Terminal window
.venv/bin/python - <<'PY'
import numpy
import sys
print("cli_executable:", sys.executable)
print("numpy_version:", numpy.__version__)
PY

Далі запустіть ті самі дві перевірки всередині ноутбука. Покладіть код у клітинку ноутбука й порівняйте вивід із виводом командного рядка. Точний шлях не треба запам’ятовувати, але він має вказувати в той самий каталог .venv проєкту.

import numpy
import sys
print("notebook_executable:", sys.executable)
print("numpy_version:", numpy.__version__)

Якщо ці шляхи різняться, встановлювати ще пакети з ноутбука зазвичай неправильний перший крок. Вам варто зареєструвати або обрати ядро ноутбука, яке вказує на середовище проєкту, а тоді повторити доказ. Головний урок: налагодження середовища — це збір доказів, а не гра в «встанови ще один пакет».

Terminal window
.venv/bin/python -m pip install ipykernel
.venv/bin/python -m ipykernel install --user --name reproducible-ai-env --display-name "Python (.venv reproducible-ai-env)"

Після вибору цього ядра в інтерфейсі ноутбука повторіть клітинку. Якщо шляхи тепер збігаються, збій був не відсутнім пакетом у середовищі проєкту; це була проблема межі інструмента. Це той самий патерн міркування, який ви пізніше використаєте для CUDA і ROCm: визначте межу, доведіть, що бачить кожна сторона, потім змініть найменший відповідальний шар.

Вибір між venv, менеджерами середовищ і контейнерами

Розділ «Вибір між venv, менеджерами середовищ і контейнерами»

Звичайний venv — базова лінія, бо вчить основний механізм, не ховаючи надто багато. Ви можете побачити шлях інтерпретатора, оглянути встановлені пакети, видалити каталог середовища й відтворити його з файлу залежностей. Для навчальних модулів і невеликих проєктів ця прозорість цінніша за хитру автоматизацію.

Інструменти вищого рівня можуть додати lock-файли, керування версією Python, розв’язання залежностей і швидші встановлення. Вони корисні, коли командам потрібна суворіша повторюваність або коли дерева залежностей стають великими. Вони не знімають потреби розуміти, який інтерпретатор активний, де встановлені пакети і чи збірка фреймворку відповідає шляху обладнання.

Контейнери додають сильнішу межу навколо користувацького простору операційної системи і шляху встановлення пакетів. Вони допомагають, коли онбординг має бути повторюваним, машини хоста непослідовні, кілька несумісних стеків мають співіснувати, або проєкт уже рухається до розгортання. Вони також додають нові поняття: шари образу, bind-монтування, інтеграція середовища виконання GPU, користувачі контейнера і взаємодія з драйвером хоста.

СитуаціяВіддавати перевагу venvВіддавати перевагу менеджеру вищого рівняВіддавати перевагу контейнеру
Соло-навчальний проєкт з одним стеком PythonНайкращий типовий вибір, бо прозорий і легко видалитиНеобов’язково, якщо ви вже розумієте основиЗазвичай зайвий, якщо хост ще не захаращений
Командний прототип із багатьма залежностямиПрацює, якщо документація дисциплінованаДобре підходить, коли важливі lock-файли і поведінка резолвераДобре підходить, коли лептопи постійно дрейфують або онбординг болісний
Кілька несумісних експериментів CUDA або ROCmРизиковано, бо бібліотеки хоста і вибір пакетів можуть зіткнутисяКорисно для пакетів Python, але не повна межа ОСІдеально підходить, коли кожен експеримент потребує окремого образу середовища виконання
Сервіс інференсу, прив’язаний до розгортанняКорисно лише для локальної розробкиКорисно для дисципліни lock-файлів перед збіркою образуІдеально підходить, бо пакування середовища виконання стає частиною поставки

Рішення має ґрунтуватися на режимах збою, а не на моді. Якщо проблема — «я не знаю, який Python використовую», контейнер сам по собі цього не навчить. Якщо проблема — «четверо розробників потребують того самого користувацького простору і стека пакетів на різних хостах», лишатися з довільним налаштуванням хоста може й далі марнувати час.

CUDA: сумісність — це контракт, а не здогадка

Розділ «CUDA: сумісність — це контракт, а не здогадка»

CUDA — обчислювальна платформа NVIDIA, і багато фреймворків глибокого навчання публікують збірки, націлені на конкретні версії середовища виконання CUDA. Драйвер, встановлений на хості, має бути достатньо новим для очікувань середовища виконання збірки фреймворку. wheel-пакет фреймворку також має бути збіркою з CUDA, а не збіркою лише для CPU, яка випадково успішно імпортується.

Практичний робочий процес CUDA починається нижче Python. Підтвердіть, що GPU видимий для операційної системи та інструментів драйвера, перш ніж встановлювати збірку фреймворку. Якщо nvidia-smi не бачить GPU, повторне встановлення PyTorch не змусить пристрій з’явитися. Якщо nvidia-smi працює, але фреймворк не може використати CUDA, наступний підозрюваний — збірка фреймворку або сумісність середовища виконання.

Terminal window
command -v nvidia-smi
nvidia-smi

Вивід nvidia-smi — не повний доказ, що PyTorch або TensorFlow працюватимуть, але він доводить щось важливе: шар драйвера NVIDIA бачить GPU. Це звужує проблему. Якщо пізніша тензорна операція впаде, ви можете зосередитися на збірці фреймворку, очікуванні середовища виконання, дозволах або прокиданні GPU в контейнері, а не гадати, чи обладнання існує.

Для PyTorch зокрема використовуйте офіційний селектор встановлення для цільової операційної системи, менеджера пакетів, версії Python і платформи обчислень. Не змішуйте випадковий wheel-пакет з одного посібника з інструментарієм CUDA з іншого, якщо ви точно не розумієте, чому ця комбінація підтримується. У більшості навчальних налаштувань wheel-пакет від фреймворку вже містить частини середовища виконання, яких очікує, а драйвер хоста лишається критичною залежністю рівня хоста.

Terminal window
.venv/bin/python - <<'PY'
try:
import torch
except ImportError:
print("torch: not installed")
else:
print("torch_version:", torch.__version__)
print("torch_cuda_build:", torch.version.cuda)
print("cuda_available:", torch.cuda.is_available())
if torch.cuda.is_available():
x = torch.tensor([1.0, 2.0], device="cuda")
print("tensor_device:", x.device)
print("tensor_sum:", float(x.sum().cpu()))
PY

Цей димовий тест розрізняє кілька випадків. Якщо torch не встановлено, ви все ще на шарі пакетів. Якщо torch.version.cuda є None, ви, ймовірно, встановили збірку для CPU. Якщо CUDA зібрано, але недоступно, уваги заслуговує межа драйвера/середовища виконання. Якщо тензорна операція вдається, у вас сильніший доказ, ніж сам імпорт.

Пауза і прогноз: Припустімо, nvidia-smi працює, torch.__version__ друкується нормально, torch.version.cuda є None, а torch.cuda.is_available() є False. Який шар, імовірно, неправильний, і чому перевстановлення драйвера NVIDIA було б малоцінним першим кроком?

Ймовірна проблема — вибір пакета фреймворку. Збірка PyTorch лише для CPU може ідеально імпортуватися, повідомляючи про відсутність підтримки збірки CUDA. Драйвер NVIDIA може все ще бути здоровим, тож його перевстановлення змінило б нижчий шар, який уже пройшов перший доказ.

ROCm: будьте суворіші до підтримуваних комбінацій

Розділ «ROCm: будьте суворіші до підтримуваних комбінацій»

ROCm відіграє подібну роль для GPU AMD, але матриця підтримки може бути чутливішою до моделі GPU, дистрибутива Linux, ядра, релізу ROCm і збірки фреймворку. Це не робить ROCm непридатним для навчання. Це означає, що офіційні настанови щодо сумісності варто ставити частиною налаштування, а не необов’язковим читанням після невдалого встановлення.

Практичний робочий процес ROCm починається з ідентифікації GPU і підтвердження, що інструменти ROCm його бачать. На системах із встановленим ROCm rocminfo і споріднені інструменти дають докази зі сторони середовища виконання. Якщо ці інструменти недоступні або не бачать обладнання, встановлення wheel-пакета фреймворку навряд чи виправить проблему нижчого шару.

Terminal window
lspci | grep -Ei 'vga|3d|display'
command -v rocminfo
rocminfo

ROCm також змінює те, як ви читаєте вивід фреймворку. Багато фреймворків показують підтримку GPU AMD через поля, пов’язані з HIP, водночас використовуючи деякі API з іменами CUDA з історичної сумісності. Таке іменування може плутати початківців: ім’я методу, що містить cuda, не завжди означає, що бекенд — NVIDIA CUDA. Вам треба оглянути повідомлену інформацію про збірку фреймворку та офіційну документацію пакета, який ви встановили.

Terminal window
.venv/bin/python - <<'PY'
try:
import torch
except ImportError:
print("torch: not installed")
else:
print("torch_version:", torch.__version__)
print("torch_cuda_build:", torch.version.cuda)
print("torch_hip_build:", torch.version.hip)
print("backend_available:", torch.cuda.is_available())
if torch.cuda.is_available():
x = torch.tensor([3.0, 4.0], device="cuda")
print("tensor_device:", x.device)
print("tensor_sum:", float(x.sum().cpu()))
PY

Урок не в тому, що кожен учень має стати експертом із драйверів GPU до навчання моделі. Урок у тому, що ROCm винагороджує дисципліновану перевірку сумісності перед встановленням пакетів. Ідентифікуйте обладнання, підтвердіть, що операційна система і версія ROCm підтримуються, оберіть задокументовану збірку фреймворку, а тоді перевірте реальною тензорною операцією.

Проєктування димового тесту, який чомусь навчає

Розділ «Проєктування димового тесту, який чомусь навчає»

Димовий тест — це невелика програма, яка доводить, що середовище може виконати мінімальну змістовну роботу, очікувану проєктом. Для середовищ ШІ сам імпорт пакета занадто слабкий. Корисний димовий тест повідомляє ідентичність інтерпретатора, версії пакетів, робочий каталог, важливі змінні середовища, видимість GPU і крихітне обчислення на задуманому бекенді.

Димовий тест варто комітити в проєкт, бо він частина контракту налаштування. Коли майбутній колега каже «середовище зламане», перше питання стає «який рядок димового тесту змінився?». Це набагато краще, ніж порівнювати знімки історії термінала або гадати, яким посібником зі встановлення скористався кожен.

Terminal window
cat > verify_env.py <<'PY'
from __future__ import annotations
import os
import platform
import subprocess
import sys
from pathlib import Path
def run_optional(command: list[str]) -> str:
try:
completed = subprocess.run(command, check=False, capture_output=True, text=True)
except FileNotFoundError:
return "not found"
first_lines = completed.stdout.strip().splitlines()[:6]
if not first_lines and completed.stderr.strip():
first_lines = completed.stderr.strip().splitlines()[:6]
return "\n".join(first_lines) if first_lines else f"exit code {completed.returncode}"
def main() -> None:
project_root = Path(__file__).resolve().parent
print("project_root:", project_root)
print("python_version:", sys.version.split()[0])
print("python_executable:", sys.executable)
print("python_prefix:", sys.prefix)
print("platform:", platform.platform())
print("virtual_env:", os.environ.get("VIRTUAL_ENV", "not set"))
import numpy
print("numpy_version:", numpy.__version__)
print("nvidia_smi:", run_optional(["nvidia-smi"]))
print("rocminfo:", run_optional(["rocminfo"]))
try:
import torch
except ImportError:
print("torch_status: not installed")
return
print("torch_version:", torch.__version__)
print("torch_cuda_build:", torch.version.cuda)
print("torch_hip_build:", torch.version.hip)
print("torch_backend_available:", torch.cuda.is_available())
if torch.cuda.is_available():
tensor = torch.tensor([1.0, 2.0, 3.0], device="cuda")
print("torch_tensor_device:", tensor.device)
print("torch_tensor_sum:", float(tensor.sum().cpu()))
else:
print("torch_tensor_device: cpu-only path")
if __name__ == "__main__":
main()
PY
.venv/bin/python verify_env.py

Цей скрипт навмисно звичайний Python, а не фреймворк тестування. На початку проєкту мета — читабельна діагностика, яку може запустити будь-який учень. Пізніше команда може перетворити частини на автоматичні перевірки CI, але виявлення локального обладнання часто лишається кроком перевірки рівня робочої станції, бо раннери CI можуть не мати того самого бекенду GPU.

Звичка старшого рівня — писати димовий тест так, щоб і успіх, і збій чомусь навчали. Якщо nvidia-smi немає, скрипт каже про це, не падаючи. Якщо PyTorch ще не встановлено, скрипт повідомляє це і чисто виходить. Якщо бекенд доступний, скрипт виконує реальну тензорну операцію, тож ви знаєте більше, ніж «пакет імпортувався».

Записи залежностей: мінімум, корисно і сильніше

Розділ «Записи залежностей: мінімум, корисно і сильніше»

Записи залежностей бувають різних рівнів. Мінімально корисний запис — файл, який дає іншій людині встановити залежності проєкту в чисте середовище. Сильніший запис відрізняє прямі залежності від розв’язаних транзитних. Ще сильніший запис включає хеші, lock-файли, образи контейнерів або перевірений процес збірки.

Для проєкту початківця найважливіша помилка, якої треба уникати, — днями редагувати середовище вручну, не оновлюючи жоден файл. Щойно робоче середовище існує лише всередині .venv, відтворюваність уже розпадається. Комітьте файл залежностей, димовий тест і README; не комітьте сам каталог .venv.

Terminal window
.venv/bin/python -m pip freeze > requirements.txt
.venv/bin/python -m pip check
.venv/bin/python verify_env.py

pip freeze не ідеальний як документ дизайну, бо записує все встановлене, включно з транзитними пакетами. Це може бути корисно для відтворення, але шумно для людського огляду. Багато команд тримають файл входу, написаний людиною, і згенерований lock-файл, або використовують інструмент, який робить це розділення явним. Принцип той самий: записуйте намір і записуйте перевірений результат.

Коли залучені фреймворки GPU, запишіть припущення про обладнання прозою так само, як і залежності. Файл вимог може сказати, який wheel-пакет встановлено, але README також має сказати, чи проєкт перевірено на CPU, CUDA, ROCm, чи на кількох шляхах. Це не дає колезі ставитися до середовища лише для CPU як до невдалого налаштування GPU або ставитися до налаштування CUDA як до портативного типового вибору.

Стратегія версій: найновіше — це не те саме, що сумісне

Розділ «Стратегія версій: найновіше — це не те саме, що сумісне»

Типова стратегія початківця — встановити найновіший драйвер, найновіший інструментарій, найновіший фреймворк і найновішу версію Python, а тоді очікувати, що вони співпрацюватимуть. Ця стратегія провалюється, бо сумісність — про перевірені комбінації, а не про індивідуальну свіжість. Зовсім нова версія Python може ще не мати wheel-пакетів для всіх пакетів, а збірка фреймворку може цілити в середовище виконання, яке припускає достатньо новий, але не довільний драйвер.

Краща стратегія — обрати якір. У багатьох проєктах ШІ версія фреймворку є якорем, бо визначає підтримувані версії Python і доступні збірки CPU, CUDA або ROCm. В інших проєктах якорем є обладнання або політика організації, бо драйвер робочої станції або базовий образ фіксовані. Щойно ви знаєте якір, обирайте решту середовища навколо нього.

Порядок рішень про сумісність
1. Визначте вимогу проєкту.
Приклад: "Нам потрібен PyTorch із прискоренням GPU для локального донавчання."
2. Визначте шлях обладнання.
Приклад: "Ця робоча станція має NVIDIA GPU, тож цільове середовище виконання — CUDA."
3. Визначте підтримувані збірки фреймворку.
Приклад: "Селектор встановлення PyTorch перелічує збірки для конкретних цілей CUDA."
4. Підтвердіть видимість драйвера хоста.
Приклад: "`nvidia-smi` бачить GPU до встановлення фреймворку."
5. Встановіть у чисте середовище проєкту.
Приклад: "Використовуйте `.venv/bin/python -m pip` і уникайте глобальних пакетів."
6. Запустіть димовий тест.
Приклад: "Тензорна операція вдається на задуманому бекенді."

Цей порядок зменшує когнітивне навантаження, бо кожен крок звужує проблему. Якщо ви спочатку встановлюєте, а міркуєте потім, кожен збій може належати кожному шару. Якщо спершу міркуєте, збій на кроці п’ять чи шість має менший простір пошуку.

Контейнери: сильніша межа, інше налагодження

Розділ «Контейнери: сильніша межа, інше налагодження»

Контейнери цінні, коли середовище хоста стало частиною проблеми. Образ контейнера може зафіксувати користувацький простір, системні пакети, пакети Python і код застосунку в повторюваній збірці. Для команд це означає, що онбординг може зміститися з «відтвори мій лептоп» на «збудуй або стягни цей образ і запусти цю команду».

Контейнери не пакують фізичний драйвер GPU так само, як пакують залежності Python. Підтримка GPU в контейнерах усе ще залежить від драйверів хоста та інтеграції середовища виконання. Саме тому контейнер CUDA може впасти на хості зі зламаним драйвером NVIDIA, а контейнер ROCm — на непідтримуваному обладнанні або без доступу до пристрою. Межа контейнера сильна, але це не магія.

Рішення, дружнє до початківця, — почати з venv, доки в проєкту немає реальної причини для сильнішої межі. Професійне рішення — контейнеризувати, коли повторюваність, вирівнювання з розгортанням або несумісні стеки виправдовують додатковий шар. Неправильне рішення — використовувати контейнери як спосіб уникнути розуміння середовища; це просто переносить плутанину в Dockerfile.

Python хоста плюс venv
ОС хоста
+-- драйвер GPU
+-- каталог проєкту
+-- .venv
+-- код проєкту
+-- димовий тест
Контейнеризований проєкт
ОС хоста
+-- драйвер GPU і інтеграція середовища виконання контейнерів
+-- образ контейнера
+-- користувацький простір ОС
+-- середовище Python
+-- код проєкту
+-- димовий тест

Якщо ви контейнеризуєте, зберігайте ту саму навчальну дисципліну. Образ має мати задокументований шлях збірки, мінімальну стратегію залежностей і димовий тест, який запускається всередині контейнера. Контейнер, який ніхто не може перебудувати, — лише більша версія недокументованого віртуального середовища.

Типові режими збою і як їх сортувати

Розділ «Типові режими збою і як їх сортувати»

Найшвидші налагоджувачі середовищ не пробують виправлення першими. Вони класифікують симптоми. Відсутній пакет, неправильний інтерпретатор, wheel-пакет лише для CPU, проблема видимості драйвера і розбіжність ядра ноутбука можуть всі давати короткі повідомлення про помилки, але вимагають різних змін.

Коли імпорт пакета падає, запитайте, який інтерпретатор запускав код і який інтерпретатор встановив пакет. Коли GPU невидимий, запитайте, чи інструмент драйвера його бачить, перш ніж звинувачувати фреймворк. Коли ноутбук не згоден із CLI, запитайте, чи ядро прив’язане до .venv проєкту. Коли перебудова падає після тижнів роботи, запитайте, чи запис залежностей справді відповідав середовищу.

Мапа сортування симптомів
+--------------------------------+-------------------------------------------+----------------------------------+
| Симптом | Перший доказ для збору | Ймовірна межа |
+--------------------------------+-------------------------------------------+----------------------------------+
| ModuleNotFoundError | надрукувати шлях інтерпретатора | середовище/пакет Python |
| CLI працює, ноутбук не працює | порівняти шляхи ноутбука і CLI | прив’язка ядра ноутбука |
| Імпорт працює, GPU недоступний | перевірити поля збірки фреймворку | фреймворк/runtime/драйвер |
| nvidia-smi не бачить GPU | запустити інструмент драйвера поза Python | видимість драйвера або хоста |
| rocminfo відсутній або падає | перевірити встановлення/підтримку ROCm | runtime ROCm або підтримка хоста |
| Перебудова дає нові версії | порівняти записи залежностей | фіксація/розв’язання залежностей |
+--------------------------------+-------------------------------------------+----------------------------------+

Старший практик також записує результат сортування. Якщо виправлення було «оберіть правильне ядро ноутбука», покладіть це в README. Якщо виправлення було «встановіть wheel-пакет фреймворку з CUDA, а не wheel-пакет для CPU», оновіть розділ встановлення. Кожен інцидент середовища — нагода прибрати одну майбутню таємницю.

Відтворюваність як командний контракт

Розділ «Відтворюваність як командний контракт»

Відтворюване середовище — не лише локальна зручність. Це контракт між людиною, яка пише код моделі, людиною, яка його рецензує, людиною, яка запускає його на іншій машині, і людиною, якій зрештою доведеться налагоджувати його, коли експеримент або демо впаде. Контракт каже, який інтерпретатор очікується, які пакети встановлено навмисно, який шлях обладнання перевірено, яка команда доводить базове здоров’я і які файли варто ігнорувати, бо вони локальні артефакти. Без цього контракту кожен колега має наново відкривати налаштування методом спроб і помилок.

Контракт має бути достатньо малим, щоб лишатися актуальним. Довгий посібник із налаштування з багатьма необов’язковими гілками може застаріти швидше за короткий посібник із надійним димовим тестом. Для цього треку корисний контракт середовища зазвичай містить очікування версії Python, команду створення локального середовища, команду встановлення залежностей, команду перевірки середовища і коротку нотатку про очікування CPU, CUDA або ROCm. Якщо проєкт пізніше отримає контейнери, контракт може додати шлях збірки й запуску контейнера, але ті самі питання все одно застосовуються.

Рецензенти мають ставитися до змін середовища як до змістовних змін коду. Оновлення вимог може змінити числову поведінку, доступні ядра, вивід токенізатора, сумісність серіалізації або поведінку середовища виконання GPU. Зміна базового образу Dockerfile може змінити системні бібліотеки. Зміна ядра ноутбука може зробити результат неможливим для відтворення. Рецензуючи pull request із МН, запитайте, чи зміна залежності або середовища навмисна, задокументована і покрита димовим тестом. Це особливо важливо, коли diff коду малий, а diff середовища великий.

Той самий контракт допомагає реагуванню на інциденти. Припустімо, запланована задача навчання починає падати після оновлення пакетів. Корисний запис середовища дає команді порівняти останній відомий справний набір залежностей, версію Python, збірку фреймворку і видимість бекенду. Без цього запису команда може годинами сперечатися, чи змінилися дані, модель, драйвер GPU, чи ноутбук використав інше ядро. Відтворюваність не запобігає кожному збою, але звужує простір пошуку, коли збої трапляються.

Дисципліна оновлень і міграцій

Розділ «Дисципліна оновлень і міграцій»

Оновлення середовища варто обробляти як міграції, а не як випадкове прибирання. Оновлення Python, NumPy, PyTorch, TensorFlow, CUDA, ROCm або базового образу контейнера може змінити сумісність збірки, поведінку бінарних розширень, числові ядра і підтримку обладнання. Безпечна міграція починається з того, що поточний димовий тест проходить, змінює одну межу за раз, коли можливо, і записує нові докази після зміни. Якщо кілька шарів змінюються разом, команда втрачає здатність сказати, який шар спричинив новий збій.

Найбезпечніша послідовність зазвичай — зберегти робоче середовище, створити свіже середовище, встановити там запропонований набір залежностей і запустити димовий тест, перш ніж щось видаляти. Цей підхід коштує місця на диску, але захищає останнє відоме справне налаштування. Для робочих станцій GPU також розумно записати вивід інструмента драйвера до і після міграції. Якщо nvidia-smi або rocminfo змінюється одночасно з пакетами Python, міграція торкнулася більше ніж однієї межі і її варто рецензувати з додатковою увагою.

Фіксація не означає заморожування назавжди. Вона означає обирати, коли зміна входить у проєкт. Проєкт навчання може навмисно оновити фреймворк, щоб використати нову можливість, покращити продуктивність або збігтися з середовищем виконання розгортання. Різниця між дисциплінованою зміною і випадковим дрейфом у тому, що дисциплінована зміна оновлює запис залежностей, документує причину, запускає перевірку і лишає ясний шлях відкату. Випадковий дрейф трапляється, коли хтось встановлює найновішу версію глобально, а проєкт повільно починає від неї залежати.

Контейнерам потрібна та сама дисципліна міграції. Перебудова образу з плаваючого тега бази може тихо змінити пакети операційної системи під сервісом моделі. Якщо образ також встановлює пакети Python без lock-файлу або обмежень, дві збірки з того самого Dockerfile можуть бути нерівноцінними. Віддавайте перевагу явним тегам бази, рецензованим записам залежностей і димовим тестам, які запускаються всередині образу. Контейнер відтворюваний лише тоді, коли його входи збірки достатньо відтворювані для рівня ризику проєкту.

Гачки CI та документації

Розділ «Гачки CI та документації»

Навіть коли перевірка GPU має відбуватися локально, безперервна інтеграція все одно може зловити багато помилок середовища. Задача CI лише для CPU може створити віртуальне середовище, встановити залежності, запустити pip check, імпортувати основні пакети, виконати модульні тести і запустити шлях CPU у verify_env.py. Це не доводить здоров’я CUDA або ROCm, але ловить зламані записи залежностей, відсутні файли, синтаксичні помилки, несумісні версії Python і випадкову залежність від глобальних пакетів. CI має робити дешеві перевірки автоматичними, щоб люди могли зосередитися на доказах, специфічних для обладнання.

Документація має показувати команди, які можна скопіювати точно. Уникайте інструкцій на кшталт «активуйте середовище і встановіть звичні пакети», бо вони ховають інтерпретатор і джерело залежностей. Віддавайте перевагу командам з явним шляхом на кшталт .venv/bin/python -m pip install -r requirements.txt і .venv/bin/python verify_env.py. Якщо важлива підтримка Windows, надайте еквівалентний шлях PowerShell, а не покладайтеся на те, що учні перекладуть. Добра документація налаштування не багатослівна; вона точна щодо меж, які часто ламаються.

README також має сказати, як виглядає успіх. Димовий тест, який друкує багато рядків, корисний лише якщо учень знає, які рядки мають значення. Для шляху лише CPU успіх може означати, що інтерпретатор вказує в .venv, numpy імпортується, а рядок бекенду ясно каже CPU-only. Для шляху CUDA успіх може означати, що nvidia-smi знайдено, фреймворк повідомляє збірку CUDA, і тензорна операція виконується на пристрої CUDA. Для шляху ROCm успіх може означати, що фреймворк повідомляє збірку HIP і тензорна операція бекенду вдається.

Коли проєкт росте, перенесіть повторювані знання про налаштування в скрипти. Файл scripts/setup-env.sh, ціль Makefile або команда запускача задач можуть зменшити помилки копіювання, але скрипт усе одно має явно викликати інтерпретатор проєкту після bootstrap. Скрипти мають голосно падати, коли використано неправильну версію Python або коли перевірки залежностей падають. Мета — не сховати середовище; мета — закодувати контракт середовища, щоб кожен учень і рецензент виконували ті самі кроки.

Коли відтворюваність зустрічає реальне обладнання

Розділ «Коли відтворюваність зустрічає реальне обладнання»

Середовища ШІ з обладнанням важчі за звичайні проєкти Python, бо частина важливого стану живе поза репозиторієм. Драйвер GPU, модуль ядра, дозволи пристрою, інтеграція середовища виконання контейнера і іноді прошивка — властивості хоста. Файл залежностей може відтворити пакети Python, але не може відтворити відсутній драйвер або непідтримувану модель GPU. Саме тому добрий посібник із середовища розділяє локальне для проєкту налаштування і передумови хоста. Проєкт може володіти .venv, вимогами, димовими тестами і ядрами ноутбуків; власник робочої станції або платформна команда зазвичай володіє встановленням драйвера і підтримкою обладнання.

Це розрізнення запобігає циклам звинувачень. Якщо димовий тест каже, що інтерпретатор проєкту правильний і пакет встановлено, але інструмент драйвера не бачить GPU, файл залежностей проєкту не перший підозрюваний. Якщо інструмент драйвера бачить GPU, а збірка фреймворку повідомляє підтримку лише CPU, вибір пакета — ймовірна межа. Якщо фреймворк повідомляє підтримку CUDA або HIP, а тензорна операція все одно падає, наступні докази можуть прийти з бібліотек середовища виконання, дозволів або розбіжності, задокументованої в нотатках сумісності фреймворку. Кожен результат вказує на менше наступне питання.

Команди мають писати очікування щодо обладнання як твердження, які можна перевірити. «Працює з GPU» — розмито. «Перевірено на Ubuntu з драйвером NVIDIA, видимим через nvidia-smi, PyTorch встановлено з селектора збірки CUDA, і verify_env.py завершує суму тензора CUDA» — це можна виконати. Для AMD еквівалентне твердження має назвати очікування підтримки ROCm і команду доказу, використану на тому хості. Такі твердження допомагають рецензентам зрозуміти, чи зміна зачіпає навчання лише на CPU, локальні експерименти з GPU, чи роботу з прискорювачем, прив’язану до розгортання.

Та сама практика допомагає, коли в учнів немає однакового обладнання. Учень лише з CPU усе одно має змогти завершити більшість уроків про середовище, якщо проєкт ясно розділяє перевірку CPU і необов’язкову перевірку прискорювача. Димовий тест може повідомити, що шлях прискорювача недоступний, не провалюючи все налаштування. Пізніше, коли учень отримає доступ до машини CUDA або ROCm, той самий димовий тест може довести додатковий бекенд. Відтворюваність має робити відмінності явними, а не вдавати, що кожна машина однакова.

Зрештою пам’ятайте, що відтворюваність — це звичка, а не один файл. Щоразу, коли ви додаєте пакет, змінюєте версію Python, перемикаєте ядро ноутбука, перебудовуєте контейнер або переходите на інше обладнання GPU, повторіть шлях перевірки й оновіть запис проєкту, якщо очікуваний вивід змінився. Ця рутина може здаватися повільною протягом першого тижня проєкту, але стає швидшою за повторне відкриття середовища з нуля після незрозумілого збою. Надійна робота з налаштування накопичується в кожному пізнішому експерименті, рецензії та розгортанні.

  • Імпорти фреймворку — слабкий доказ: Фреймворк глибокого навчання може успішно імпортуватися, навіть якщо його встановлено як збірку лише для CPU, тож реальна тензорна операція бекенду — сильніший крок перевірки, ніж сам import torch.

  • Ядра ноутбуків — окремі вибори виконання: Активація .venv у терміналі не гарантує, що наявний сервер ноутбуків або редактор обрав той самий інтерпретатор, тож шлях треба перевіряти всередині самого ноутбука.

  • Контейнери GPU все ще залежать від драйверів хоста: Образи контейнерів можуть пакувати бібліотеки користувацького простору і залежності Python, але доступ до GPU NVIDIA і AMD усе ще потребує сумісного драйвера хоста та інтеграції середовища виконання.

  • Lock-файл — не доказ обладнання: Записи залежностей допомагають відтворити пакети, але не доводять, що робоча станція має очікуваний GPU, драйвер, дозволи або підтримуваний шлях ROCm/CUDA.

ПомилкаЩо йде не такКращий хід
Повторне використання одного глобального середовища Python для кожного проєкту ШІЗіткнення залежностей наростають повільно, і імпорти починають залежати від випадкового порядку встановлення, а не від наміру проєктуСтворіть одне локальне для проєкту .venv, встановлюйте лише залежності проєкту і задокументуйте шлях налаштування
Запуск pip install через один інтерпретатор, а скриптів — через іншийВстановлення виглядає успішним, але застосунок не знаходить пакети або бачить інші версіїВикористовуйте .venv/bin/python -m pip і запускайте перевірку через той самий шлях .venv/bin/python
Ставитися до успішного імпорту фреймворку як до перевірки GPUЗбірки лише для CPU і зламані шляхи середовища виконання все одно можуть імпортуватися, тож перша реальна тензорна операція падає пізнішеЗапустіть димовий тест, який повідомляє поля збірки і виконує крихітну тензорну операцію на задуманому бекенді
Встановлювати фреймворки до перевірки видимості драйвера GPUПовідомлення про помилки охоплюють надто багато шарів, тож неясно, чи відповідальні обладнання, драйвер, середовище виконання чи PythonСпочатку перевірте nvidia-smi або rocminfo, потім встановіть збірку фреймворку, яка відповідає обраному бекенду
Припускати, що активація ноутбука йде за активацією терміналаНоутбук використовує старе ядро, а CLI — середовище проєкту, створюючи суперечливі результатиНадрукуйте шлях інтерпретатора всередині ноутбука і зареєструйте ядро з .venv проєкту, коли потрібно
Змішувати менеджери пакетів без письмової стратегіїПакети приходять із кількох джерел, оновлення стають важкими для пояснення, а перебудови різняться між машинамиОберіть одну первинну стратегію середовища на проєкт і запишіть будь-які винятки в README
Контейнеризувати до розуміння шару, що падаєКоманда отримує складність образу, монтування, користувачів і середовища виконання GPU, а початкова плутанина Python лишаєтьсяВикористовуйте контейнери, коли повторюваність або потреби розгортання їх виправдовують, і зберігайте ту саму дисципліну димового тесту
Комітити .venv або згенеровані виводи в GitРепозиторій стає великим, специфічним для платформи і важчим для клонування чи рецензування іншимиКомітьте файли залежностей, нотатки налаштування і скрипти перевірки; ігноруйте локальні середовища і згенеровані артефакти

Q1. Ваша команда успадковує репозиторій навчання, де README.md каже лише «install requirements», і двоє розробників повідомляють різні версії numpy після виконання цієї інструкції. Які докази середовища ви б додали першими і чому ці докази зменшують простір налагодження?

Відповідь Додайте шлях локального для проєкту середовища, запис залежностей і димовий тест, який друкує шлях інтерпретатора та версії пакетів. Це зменшує простір налагодження, бо команда може відрізнити «інший інтерпретатор» від «інше розв’язання залежностей», замість ставитися до обох як до загального збою встановлення. Найсильніша негайна звичка — запускати встановлення і перевірку через `.venv/bin/python`, щоб сама команда називала середовище, яке тестується.

Q2. Учень повідомляє, що ноутбук не може імпортувати пакет, але .venv/bin/python -c "import package_name" працює в каталозі проєкту. Що варто перевірити перед перевстановленням залежностей і який результат підтвердив би вашу діагностику?

Відповідь Перевірте шлях інтерпретатора ноутбука з клітинки ноутбука і порівняйте його зі шляхом інтерпретатора CLI. Якщо шлях ноутбука не вказує в `.venv` проєкту, проблема — розбіжність прив’язки ядра, а не відсутній пакет у середовищі проєкту. Реєстрація або вибір ядра на базі `.venv/bin/python` має змусити ноутбук і CLI збігтися.

Q3. Робоча станція NVIDIA проходить nvidia-smi, але PyTorch повідомляє torch.version.cuda як None, а torch.cuda.is_available() як False. Який шар варто змінити першим і якої спокусливої зміни варто уникати?

Відповідь Спочатку змініть вибір пакета фреймворку, бо встановлена збірка PyTorch виглядає як лише для CPU. Уникайте перевстановлення драйвера NVIDIA як першого кроку, бо `nvidia-smi` уже дав доказ, що драйвер бачить GPU. Наступна дія — встановити збірку PyTorch, яка відповідає задуманій цілі CUDA, потім повторити димовий тест із реальною тензорною операцією.

Q4. Команда з GPU AMD встановлює випадкові версії пакетів із кількох дописів у блогах, а тоді бачить різну поведінку ROCm на двох робочих станціях Linux. Як їм перепроєктувати процес налаштування перед тим, як пробувати ще команди пакетів?

Відповідь Вони мають почати з перевірки підтримуваної комбінації: ідентифікувати моделі GPU, підтвердити, що дистрибутив Linux і реліз ROCm підтримуються, обрати задокументовану збірку фреймворку і встановити в чисте середовище проєкту. Налаштування ROCm менш прощають, коли обладнання, дистрибутив, середовище виконання і збірки фреймворку змішують недбало. Димовий тест має повідомляти інформацію HIP/збірки і виконувати невелику тензорну операцію бекенду, коли вона доступна.

Q5. Прототип почався як соло-проєкт venv, але тепер шестеро розробників потребують того самого налаштування, машини хоста постійно дрейфують, а сервіс рухається до розгортання. Чи варто команді лишатися лише з Python хоста і який компроміс обґрунтовує вашу рекомендацію?

Відповідь Це сильний випадок для введення контейнерів, бо повторюваний онбординг, вирівнювання з розгортанням і дрейф хоста тепер реальні проблеми. Компроміс у тому, що контейнери додають збірки образів, конфігурацію середовища виконання, монтування, користувачів і питання прокидання GPU. Рекомендація виправдана, бо сильніша межа розв’язує конкретну командну проблему, а не тому, що контейнери автоматично простіші.

Q6. Димовий тест імпортує torch і успішно виходить, тож учень позначає середовище CUDA як перевірене. Пізніше навчання тихо виконується на CPU. Як би ви покращили димовий тест, щоб зловити це раніше?

Відповідь Димовий тест має повідомляти поля збірки фреймворку, як-от версію CUDA або HIP, повідомляти доступність бекенду і виконувати крихітну тензорну операцію на задуманому пристрої. Успіх імпорту доводить лише, що Python може завантажити пакет. Реальна тензорна операція доводить набагато більше: збірка фреймворку, шлях середовища виконання і доступ до пристрою достатньо узгоджені для мінімального обчислення.

Q7. Під час перебудови pip install -r requirements.txt вдається, але pip check повідомляє конфлікти залежностей, і модель поводиться інакше, ніж минулого тижня. Що це підказує про запис залежностей проєкту і як команді варто відповісти?

Відповідь Це підказує, що запис залежностей недостатньо сильний, щоб відтворити раніше перевірене середовище, або що в середовище дозволили несумісні версії. Команда має розділити прямі залежності від розв’язаних версій, перегенерувати або відремонтувати запис у стилі lock-файлу з відомого справного середовища, запустити `pip check` і повторити димовий тест. Якщо проєкту потрібна суворіша повторюваність, може бути виправданий інструмент lock-файлів вищого рівня або збірка контейнера.

Мета: збудувати чисте середовище проєкту ШІ, задокументувати його і довести, чи воно зараз лише для CPU, здатне до CUDA, чи здатне до ROCm. Вам не потрібен GPU, щоб завершити вправу; якщо інструментів GPU немає, димовий тест має ясно повідомити про це, а не вдавати, що бекенд доступний.

  • Створіть свіжий каталог проєкту з локальним віртуальним середовищем і підтвердіть, що шлях інтерпретатора належить проєкту.
Terminal window
mkdir -p reproducible-ai-env/src reproducible-ai-env/notebooks reproducible-ai-env/data reproducible-ai-env/outputs
cd reproducible-ai-env
python3.12 -m venv .venv
.venv/bin/python -m pip install --upgrade pip setuptools wheel
.venv/bin/python -c "import sys; print(sys.version); print(sys.executable); print(sys.prefix)"
  • Додайте мінімальний файл входу залежностей, встановіть через інтерпретатор проєкту і запишіть розв’язане середовище.
Terminal window
cat > requirements.in <<'EOF'
numpy
packaging
EOF
.venv/bin/python -m pip install -r requirements.in
.venv/bin/python -m pip freeze > requirements.txt
.venv/bin/python -m pip check
  • Створіть README, який документує контракт налаштування, якого має дотримуватися інший учень.
Terminal window
cat > README.md <<'EOF'
# Reproducible AI Environment
## Setup
Use Python 3.12 to create `.venv`, then run package commands through `.venv/bin/python`.
## Install
`.venv/bin/python -m pip install -r requirements.txt`
## Verify
`.venv/bin/python verify_env.py`
## Hardware expectation
This project may run CPU-only unless the smoke test reports a working CUDA or ROCm backend.
EOF
  • Додайте .gitignore, щоб локальні середовища і згенеровані артефакти не вважалися джерелом проєкту.
Terminal window
cat > .gitignore <<'EOF'
.venv/
__pycache__/
.ipynb_checkpoints/
outputs/
*.pyc
EOF
  • Огляньте інструменти GPU перед встановленням будь-якого пакета CUDA або ROCm, специфічного для фреймворку.
Terminal window
lspci | grep -Ei 'vga|3d|display' || true
command -v nvidia-smi || true
command -v rocminfo || true
  • Створіть димовий тест, який повідомляє ідентичність інтерпретатора, здоров’я пакетів, необов’язкові інструменти GPU і необов’язковий стан бекенду фреймворку.
Terminal window
cat > verify_env.py <<'PY'
from __future__ import annotations
import os
import platform
import subprocess
import sys
from pathlib import Path
def optional_output(command: list[str]) -> str:
try:
completed = subprocess.run(command, check=False, capture_output=True, text=True)
except FileNotFoundError:
return "not found"
combined = completed.stdout.strip() or completed.stderr.strip()
if not combined:
return f"exit code {completed.returncode}"
return "\n".join(combined.splitlines()[:8])
def main() -> None:
print("project_root:", Path(__file__).resolve().parent)
print("python_version:", sys.version.split()[0])
print("python_executable:", sys.executable)
print("python_prefix:", sys.prefix)
print("platform:", platform.platform())
print("virtual_env:", os.environ.get("VIRTUAL_ENV", "not set"))
import numpy
print("numpy_version:", numpy.__version__)
print("nvidia_smi_status:", optional_output(["nvidia-smi"]))
print("rocminfo_status:", optional_output(["rocminfo"]))
try:
import torch
except ImportError:
print("torch_status: not installed")
print("backend_status: CPU-only verification path completed")
return
print("torch_version:", torch.__version__)
print("torch_cuda_build:", torch.version.cuda)
print("torch_hip_build:", torch.version.hip)
print("torch_backend_available:", torch.cuda.is_available())
if torch.cuda.is_available():
value = torch.tensor([5.0, 7.0], device="cuda").sum().cpu().item()
print("torch_tensor_backend: cuda-compatible API")
print("torch_tensor_sum:", value)
else:
print("torch_tensor_backend: cpu-only path")
if __name__ == "__main__":
main()
PY
.venv/bin/python verify_env.py
  • Відтворіть середовище із записаного файлу залежностей і підтвердіть, що та сама команда перевірки все ще працює.
Terminal window
rm -rf .venv
python3.12 -m venv .venv
.venv/bin/python -m pip install --upgrade pip setuptools wheel
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m pip check
.venv/bin/python verify_env.py

Критерії успіху:

  • Проєкт містить .venv, requirements.in, requirements.txt, README.md, .gitignore і verify_env.py.

  • Команди перевірки використовують .venv/bin/python після створення середовища bootstrap.

  • requirements.txt може відтворити встановлені пакети в свіжому .venv.

  • verify_env.py друкує шлях інтерпретатора, версію Python, корінь проєкту, платформу і версію numpy.

  • Огляд GPU повідомляє, чи доступні nvidia-smi або rocminfo, не провалюючи весь димовий тест, коли якийсь інструмент відсутній.

  • Якщо PyTorch встановлено пізніше, димовий тест розрізняє докази лише CPU, збірки CUDA і збірки HIP, перш ніж стверджувати успіх бекенду.

  • README каже майбутньому учню, як встановити і перевірити середовище, не покладаючись на вашу історію термінала.

  • Python documentation: venv — Офіційна довідка зі створення ізольованих віртуальних середовищ Python.
  • Python Packaging User Guide: Installing Packages — Пояснює робочі процеси встановлення пакетів і використання віртуальних середовищ.
  • pip documentation: pip check — Документує перевірки узгодженості залежностей, використані в робочому процесі перевірки модуля.
  • pip documentation: requirements file format — Визначає, як файли requirements.txt інтерпретує pip.
  • IPython documentation: Installing the IPython kernel — Охоплює реєстрацію інтерпретатора проєкту як ядра ноутбука.
  • Jupyter documentation: Kernels — Пояснює, як ноутбуки обирають ядро виконання, яке запускає код.
  • PyTorch: Get Started — Надає офіційні селектори встановлення для збірок CPU, CUDA і ROCm.
  • PyTorch documentation: CUDA semantics — Документує поведінку CUDA в PyTorch і перевірки пристрою.
  • NVIDIA documentation: CUDA Compatibility — Пояснює очікування сумісності драйвера і середовища виконання CUDA.
  • AMD ROCm documentation: Compatibility matrix — Перелічує підтримувані комбінації операційної системи, обладнання і програмного забезпечення ROCm.
  • Docker documentation: Build with Dockerfile — Надає офіційний фон для файлів збірки образів контейнерів.
  • NVIDIA Container Toolkit documentation — Пояснює інтеграцію середовища виконання GPU для контейнерів на системах NVIDIA.
  • github.com: RELEASE.md — Upstream RELEASE.md PyTorch містить матрицю сумісності релізів із явними стовпцями Python, CUDA і ROCm.
  • PyTorch CUDA semantics docs — Документація семантики CUDA в PyTorch явно показує torch.cuda.is_available() у прикладах вибору пристрою і обговорює, що робить ця перевірка.
  • github.com: hip.rst — Документація семантики HIP у PyTorch явно стверджує, що HIP повторно використовує інтерфейси torch.cuda, і показує перевірки torch.version.hip проти torch.version.cuda.
  • github.com: nvidia container toolkit — README NVIDIA Container Toolkit каже, що інструментарій налаштовує контейнери на використання GPU NVIDIA і явно вимагає драйвер NVIDIA на хості.