کار با پروژههای مختلف یادگیری ماشین و هوش مصنوعی معمولاً با مشکلی تکراری روبهرو میشود: پروژهای به نسخهی خاصی از PyTorch نیاز دارد و پروژهای دیگر به نسخهای متفاوت. ارتقا یا تنزل بستهها بهشکل سراسری روی سیستم باعث خرابی سایر پروژهها میشود؛ وضعیتی که به «جهنم وابستگیها» معروف است. ایجاد محیطهای مجازی ایزوله راهکاری ضروری برای پیشگیری از این تداخلهاست.
در پروژههای مدرن هوش مصنوعی، بهدلیل تنوع ابزارها و نیازمندیهای سختافزاری، تفکیک وابستگیها اهمیت دوچندانی دارد. این درس روشهای استاندارد ایزولهسازی محیطهای پایتون را با ابزارهایی مثل uv، venv و conda بررسی میکند تا بتوانید بستههای هر پروژه و هماهنگی آنها با نسخههای مختلف CUDA را بهصورت پایدار مدیریت کنید.
همچنین با توجه به اینکه دانلود از مخازنی مانند PyPI گاهی از داخل ایران با کندی یا ناپایداری روبهرو میشود، استفاده از ابزارهای پرسرعت مثل uv یا تنظیم میرورهای معتبر میتواند روند دانلود و نصب بستهها را پایدارتر کند.
«جهنم وابستگیها» واقعی است؛ محیط مجازی (Virtual environment) داروی درمان آن است.
اهداف یادگیری
- ساخت محیطهای مجازی ایزوله با
uv،venvیاconda - نوشتن فایل
pyproject.tomlبههمراه گروههای وابستگی اختیاری و تولید فایل قفل (Lockfile) برای تکرارپذیری - عیبیابی و رفع مشکلات رایج: نصب سراسری (Global)، ترکیب ناهمگون pip و conda، و ناهماهنگی نسخههای CUDA
- پیادهسازی استراتژی تفکیک محیط بر اساس هر فاز برای پروژههایی با وابستگیهای متناقض
صورت مسئله
برای یک پروژهی فاینتیونینگ (Fine-tuning)، PyTorch 2.4 را نصب میکنید. هفتهی بعد، پروژهی دیگری دقیقاً به نسخهی خاصی از PyTorch 2.1 نیاز دارد، چون بیلد CUDA آن قفل شده است. نسخه را بهصورت سراسری روی سیستم ارتقا میدهید و پروژهی اول از کار میافتد. نسخه را برمیگردانید و پروژهی دوم خراب میشود.
این همان «جهنم وابستگیها» است؛ مشکلی همیشگی در پروژههای هوش مصنوعی و یادگیری ماشین، به این دلایل:
- فریمورکهای PyTorch، JAX و TensorFlow هرکدام با بایندرهای CUDA اختصاصی خودشان عرضه میشوند
- کتابخانههای مدل روی نسخههای خاصی از فریمورکها قفل شدهاند
- یک دستور
pip installسراسری، هر پکیجی را که قبلاً روی سیستم بوده بازنویسی میکند - بیلدهای CUDA 11.8 با درایورهای CUDA 12.x کار نمیکنند (و برعکس)
راهحل: هر پروژه باید محیط ایزولهی اختصاصی خودش را داشته باشد، با پکیجهای مستقل خودش.
مفهوم اصلی
پیادهسازی
گزینهی 1: uv venv (پیشنهادی)
ابزار uv سریعترین مدیر بسته (Package manager) پایتون است (10 تا 100 برابر سریعتر از pip). این ابزار مدیریت محیطهای مجازی، نسخههای پایتون و حل وابستگیها را یکپارچه در قالب یک ابزار واحد انجام میدهد.
curl -LsSf https://astral.sh/uv/install.sh | sh
uv python install 3.12
cd your-project
uv venv
source .venv/bin/activate
نصب پکیجها:
uv pip install torch numpy
ساخت یک پروژه بههمراه فایل pyproject.toml فقط در یک مرحله:
uv init my-ai-project
cd my-ai-project
uv add torch numpy matplotlib
گزینهی 2: venv (پیشفرض پایتون)
اگر امکان نصب uv را ندارید، پایتون بهصورت پیشفرض همراه با venv عرضه میشود:
python3 -m venv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windows
pip install torch numpy
سرعتش کمتر از uv است، اما هر جا که پایتون نصب باشد کار میکند.
گزینهی 3: conda (در مواقع نیاز)
ابزار Conda وابستگیهای غیرپایتونی مثل مجموعهابزار CUDA، cuDNN و کتابخانههای C را هم مدیریت میکند. در این شرایط سراغ آن بروید:
- به نسخهی خاصی از مجموعهابزار CUDA نیاز دارید، بدون آنکه بخواهید آن را روی کل سیستم نصب کنید
- روی کلاستر (Cluster) اشتراکی کار میکنید و اجازهی نصب پکیجهای سیستمی را ندارید
- در دستورالعمل نصب یک کتابخانه رسماً نوشته شده: "use conda"
# نصب miniconda (نه نسخه کامل Anaconda)
curl -LsSf https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o miniconda.sh
bash miniconda.sh -b
conda create -n myproject python=3.12
conda activate myproject
conda install pytorch torchvision torchaudio pytorch-cuda=12.4 -c pytorch -c nvidia
یک قانون: اگر برای ساخت یک محیط از conda استفاده کردید، تمام پکیجهای آن محیط را هم با conda نصب کنید. ترکیب pip install با محیط conda تناقضهایی در وابستگیها ایجاد میکند که دیباگکردنشان عذابآور است.
برای این دوره: استراتژی تفکیک بر اساس فاز
میتوانید برای کل این دوره یک محیط بسازید؛ اما این کار را نکنید. فازهای مختلف به وابستگیهای متفاوتی (که گاهی با هم در تناقضاند) نیاز دارند.
استراتژی:
ai-engineering-from-scratch/
├── .venv/ <-- shared lightweight env for phases 0-3
├── phases/
│ ├── 04-neural-networks/
│ │ └── .venv/ <-- PyTorch env
│ ├── 05-cnns/
│ │ └── .venv/ <-- same PyTorch env (symlink or shared)
│ ├── 08-transformers/
│ │ └── .venv/ <-- might need different transformer versions
│ └── 11-llm-apis/
│ └── .venv/ <-- API SDKs, no torch needed
اسکریپت موجود در مسیر code/env_setup.sh محیط پایهی این دوره را برایتان میسازد.
مبانی pyproject.toml
هر پروژهی پایتونی باید یک فایل pyproject.toml داشته باشد. این فایل تمام فایلهای setup.py، setup.cfg و requirements.txt را در قالب یک فایل واحد جایگزین میکند.
[project]
name = "ai-engineering-from-scratch"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26",
"matplotlib>=3.8",
"jupyter>=1.0",
"scikit-learn>=1.4",
]
[project.optional-dependencies]
torch = ["torch>=2.3", "torchvision>=0.18"]
llm = ["anthropic>=0.39", "openai>=1.50"]
سپس برای نصب:
uv pip install -e ".[torch]" # base + PyTorch
uv pip install -e ".[llm]" # base + LLM SDKs
uv pip install -e ".[torch,llm]" # everything
فایلهای قفل (Lockfiles)
فایل قفل تمام وابستگیها (حتی وابستگیهای غیرمستقیم را) روی نسخهی کاملاً دقیق و مشخصی قفل میکند. این کار تکرارپذیری را تضمین میکند: هر کسی که از روی فایل قفل نصب کند، دقیقاً همان پکیجها برایش نصب خواهد شد.
# ابزار uv هنگام استفاده از uv add بهطور خودکار uv.lock را تولید میکند
uv add numpy
# رویکرد pip-tools
uv pip compile pyproject.toml -o requirements.lock
uv pip install -r requirements.lock
فایل قفل را در گیت commit کنید. وقتی فردی مخزن (Repository) را کلون کند، پکیجها را از روی فایل قفل نصب خواهد کرد و نسخههایی کاملاً یکسان دریافت میکند.
اشتباهات رایج
1. نصب پکیجها بهصورت سراسری
pip install torch # BAD: installs to system Python
source .venv/bin/activate
pip install torch # GOOD: installs to virtual environment
بررسی محل نصب پکیجها:
which python # should show .venv/bin/python, not /usr/bin/python
which pip # should show .venv/bin/pip
2. ترکیب pip و conda
conda create -n myenv python=3.12
conda activate myenv
conda install pytorch -c pytorch
pip install some-other-package # BAD: can break conda's dependency tracking
conda install some-other-package # GOOD: let conda manage everything
اگر ناچار شدید داخل محیط conda از pip استفاده کنید (چون بعضی پکیجها فقط روی pip موجودند)، اول همهی پکیجهای conda را نصب کنید و پکیجهای pip را در آخر کار بیاورید.
3. فراموشکردن فعالسازی محیط
python train.py # uses system Python, missing packages
source .venv/bin/activate
python train.py # uses project Python, packages found
پرامپت (Prompt) شل شما باید نام محیط را نشان دهد:
(.venv) $ python train.py
4. کامیتکردن .venv در گیت
echo ".venv/" >> .gitignore
حجم محیطهای مجازی بین 200MB تا 2GB است. این محیطها محلیاند و بین سیستمهای مختلف قابل انتقال نیستند. بهجای آن، فایل pyproject.toml و فایل قفل را commit کنید.
5. ناهماهنگی نسخهی CUDA
nvidia-smi # shows driver CUDA version (e.g., 12.4)
python -c "import torch; print(torch.version.cuda)" # shows PyTorch CUDA version
# این موارد باید سازگار باشند.
# PyTorch CUDA version must be <= driver CUDA version.
بهکارگیری عملی
اسکریپت راهاندازی را اجرا کنید تا محیط دورهی شما ساخته شود:
bash phases/00-setup-and-tooling/06-python-environments/code/env_setup.sh
این کار یک .venv در ریشهی مخزن میسازد و وابستگیهای اصلی را نصب و صحتسنجی میکند.
تمرینها
- اسکریپت
env_setup.shرا اجرا کنید و مطمئن شوید همهی بررسیها پاس میشوند - یک محیط مجازی دوم بسازید، نسخهی متفاوتی از numpy را روی آن نصب کنید و مطمئن شوید این دو محیط از هم ایزولهاند
- یک فایل
pyproject.tomlبرای پروژهای بنویسید که همزمان به PyTorch و Anthropic SDK نیاز دارد - بهعمد یک پکیج را بهصورت سراسری نصب کنید (بدون فعالسازی venv)، دقت کنید کجا نصب میشود و سپس آن را حذف کنید
راهنماییها
تمرین 1. دستور bash phases/00-setup-and-tooling/06-python-environments/code/env_setup.sh را از ریشهی مخزن اجرا کنید. هر خط خروجی را بخوانید؛ اگر بررسی خاصی رد شد، همان یک مورد را برطرف کنید و اسکریپت را دوباره اجرا کنید تا هیچ خطایی نماند.
تمرین 2. محیط دوم را با دستور uv venv در یک پوشهی جدید بسازید، آن را فعال کنید و یک نسخهی قدیمیتر از numpy را با تعیین دقیق نسخه نصب کنید (مانند numpy==1.26.4). در هر دو محیط دستور python -c "import numpy; print(numpy.__version__)" را اجرا کنید؛ دو نسخه حتماً باید متفاوت باشند.
تمرین 3. از مثال بخش «مبانی pyproject.toml» شروع کنید و نامهای torch و anthropic را ذیل dependencies بیاورید. دستور uv pip install -e . یا uv sync را در یک محیط جدید اجرا کنید؛ اگر هر دو پکیج بدون خطا ایمپورت شدند، فایل درست تنظیم شده است.
تمرین 4. همهی محیطها را غیرفعال (deactivate) کنید، دستور pip install --user <small package> را اجرا کنید، سپس با pip show <package> خط Location را بخوانید. پکیج را با pip uninstall <package> حذف کنید و دوباره با pip show بررسی کنید که حذف شده باشد.
اصطلاحات کلیدی
| اصطلاح | در گفتار عامیانه | معنای فنی دقیق |
|---|---|---|
| Virtual environment | «یک venv» | دایرکتوری ایزولهای شامل یک مفسر پایتون و پکیجها، مجزا از پایتون سراسری سیستم |
| Lockfile | «وابستگیهای قفلشده» | فایلی حاوی نام و نسخهی دقیق تمام پکیجها که نصب یکسان روی همهی ماشینها را تضمین میکند |
| pyproject.toml | «همان setup.py جدید» | فایل پیکربندی استاندارد پروژههای پایتون که جایگزین setup.py ،setup.cfg و requirements.txt شده است |
| Transitive dependency | «وابستگیِ یک وابستگی» | پکیج B به C وابسته است؛ اگر پکیج A را که به B وابسته است نصب کنید، C وابستگی غیرمستقیم A محسوب میشود |
| CUDA mismatch | «کارت گرافیکم کار نمیکند» | کتابخانهی PyTorch برای نسخهای از CUDA کامپایل شده که با نسخهی پشتیبانیشده توسط درایور کارت گرافیک سیستم همخوانی ندارد |
