فاز 0 · درس 6

مدیریت محیط‌های مجازی پایتون: فرار از جهنم وابستگی‌ها

نوع
ساختنی
زمان
حدود 30 دقیقه
زبان‌ها
Shell
چند جعبه شفاف شیشه‌ای مکعبی مجزا در کنار هم که داخل هرکدام ابزارها و قطعات متفاوتی بدون تداخل قرار گرفته‌اند
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفهوم اصلی
  4. پیاده‌سازی
  5. گزینه‌ی 1: uv venv (پیشنهادی)
  6. گزینه‌ی 2: venv (پیش‌فرض پایتون)
  7. گزینه‌ی 3: conda (در مواقع نیاز)
  8. برای این دوره: استراتژی تفکیک بر اساس فاز
  9. مبانی pyproject.toml
  10. فایل‌های قفل (Lockfiles)
  11. اشتباهات رایج
  12. 1. نصب پکیج‌ها به‌صورت سراسری
  13. 2. ترکیب pip و conda
  14. 3. فراموش‌کردن فعال‌سازی محیط
  15. 4. کامیت‌کردن .venv در گیت
  16. 5. ناهماهنگی نسخه‌ی CUDA
  17. به‌کارگیری عملی
  18. تمرین‌ها
  19. راهنمایی‌ها
  20. اصطلاحات کلیدی

کار با پروژه‌های مختلف یادگیری ماشین و هوش مصنوعی معمولاً با مشکلی تکراری روبه‌رو می‌شود: پروژه‌ای به نسخه‌ی خاصی از 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 کار نمی‌کنند (و برعکس)

راه‌حل: هر پروژه باید محیط ایزوله‌ی اختصاصی خودش را داشته باشد، با پکیج‌های مستقل خودش.

مفهوم اصلی

با محیط مجازیبدون محیط مجازیپایتون سیستمtorch 2.4.0 (CUDA 12.4)پروژه A به این نیاز داردtorch 2.1.0 (CUDA 11.8)پروژه B به این نیاز داردتداخل: فقط یک نسخهtorch می‌تواند وجود داشته باشدپروژه A (.venv/)torch 2.4.0 (CUDA 12.4)transformers 4.44پروژه B (.venv/)torch 2.1.0 (CUDA 11.8)diffusers 0.28
ایزوله‌سازی وابستگی‌هاهر پروژه torch اختصاصی خود را دارد؛ نصب سراسری دچار تداخل می‌شود
DEPENDENCY ISOLATIONBoth pins are correct, they just cannot share one interpreter. Installed globally, the second pip install overwrites the first and both projects break. A per-project virtual environment gives each its own site-packages, so torch 2.4 and torch 2.1 coexist on the same machine without ever meeting.project-a.venvtorch 2.4 · cu124project-b.venvtorch 2.1 · cu118site-packages سراسریtorch 2.4torch 2.1torch 2.؟ · هر دو خراب شدندیک مفسر برای هر پروژه؛ پکیج‌ها داخل همان حل‌وفصل می‌شوند
هر دو نسخه مشخص‌شده معتبر هستند، فقط نمی‌توانند یک مفسر مشترک داشته باشند. در صورت نصب سراسری، دومین pip install نسخه اول را بازنویسی کرده و هر دو پروژه از کار می‌افتند. یک محیط مجازی مجزا برای هر پروژه، یک site-packages اختصاصی فراهم می‌کند تا torch 2.4 و torch 2.1 بدون هیچ تداخلی روی یک سیستم کنار هم اجرا شوند.

پیاده‌سازی

ابزار 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 در ریشه‌ی مخزن می‌سازد و وابستگی‌های اصلی را نصب و صحت‌سنجی می‌کند.

تمرین‌ها

  1. اسکریپت env_setup.sh را اجرا کنید و مطمئن شوید همه‌ی بررسی‌ها پاس می‌شوند
  2. یک محیط مجازی دوم بسازید، نسخه‌ی متفاوتی از numpy را روی آن نصب کنید و مطمئن شوید این دو محیط از هم ایزوله‌اند
  3. یک فایل pyproject.toml برای پروژه‌ای بنویسید که هم‌زمان به PyTorch و Anthropic SDK نیاز دارد
  4. به‌عمد یک پکیج را به‌صورت سراسری نصب کنید (بدون فعال‌سازی 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 کامپایل شده که با نسخه‌ی پشتیبانی‌شده توسط درایور کارت گرافیک سیستم همخوانی ندارد

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسمحیط‌های مجازی چه مشکلی را حل می‌کنند؟
  2. پیش از درسدر زمینه مدیریت وابستگی‌های پایتون، lockfile چیست؟
  3. پس از درسچگونه مطمئن می‌شوید دستورات pip و python از محیط مجازی استفاده می‌کنند و نه از پایتون سیستم؟
  4. پس از درسچرا ترکیب pip و conda در یک محیط واحد مشکل‌ساز است؟
  5. پس از درسکد PyTorch شما با وجود کارت گرافیک NVIDIA خطای 'CUDA not available' می‌دهد. محتمل‌ترین دلیل چیست؟

سؤالات متداول

چرا استفاده از uv به‌جای pip و venv توصیه می‌شود؟

ابزار uv بسیار سریع‌تر از pip است (بین 10 تا 100 برابر) و مدیریت نسخه‌های پایتون، محیط‌های مجازی و تفکیک وابستگی‌ها را یکپارچه انجام می‌دهد.

چه زمانی باید به‌جای uv یا venv از conda استفاده کرد؟

هنگامی که به وابستگی‌های غیرپایتونی مثل نسخه‌های خاصی از ابزارهای CUDA یا cuDNN بدون دسترسی سیستمی (مثل کلاسترهای اشتراکی) نیاز است.

چرا نباید پوشه venv را در گیت کامیت کرد؟

محیط‌های مجازی حجم زیادی دارند (بین 200 مگابایت تا 2 گیگابایت)، مختص همان سیستم هستند و منتقل نمی‌شوند؛ به‌جای آن باید فایل pyproject.toml و فایل قفل (lockfile) کامیت شوند.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.