Ollama یا vLLM؛ کدام server را اجرا کنیم؟
برای یک کاربر و حتی سیستم فقط CPU، Ollama انتخاب سادهتری است؛ اما vLLM برای سرویسدهی همزمان به چند درخواست روی GPU ساخته شده است. تفاوت واقعی را ببینید.
Ollama در برابر vLLM، در یک پاراگراف
Ollama یک مدیر مدل بههمراه یک server است: وزنهای quantized را دانلود و بارگذاری میکند و در 127.0.0.1:11434 پاسخ میدهد؛ اگر سیستم فقط CPU داشته باشد، از CPU استفاده میکند. vLLM یک موتور throughput است: GPU را با اجرای همزمان درخواستهای متعدد در حالت اشباع نگه میدارد و روی ماشینی که GPU ندارد، ابزار مناسبی نیست. تصمیمگیری به همین خلاصه میشود. گفتوگوی یک کاربر با یک دستیار محلی، یک کار Ollama است. برنامهای که به یک تیم سرویس میدهد، یک کار vLLM است.
هر دو از HTTP API سازگار با OpenAI استفاده میکنند؛ بنابراین کد client با تغییر base URL بین آنها جابهجا میشود. تفاوت در API نیست. تفاوت در این است که وقتی درخواست دوم، پیش از پایان تولید tokenهای درخواست اول، وارد میشود چه اتفاقی رخ میدهد.
Ollama در واقع چیست
Ollama یک لایه برای سهولت استفاده است. این ابزار با یک فرمان نصب، یک رجیستری مدل (ollama pull llama3.1:8b)، یک مخزن محلی برای وزنهای مدل، یک اعلان گفتوگو، یک سرویس systemd و یک API مبتنی بر HTTP در اختیار شما قرار میدهد. مدلهایی که این ابزار ارائه میکند، فایلهای GGUF هستند و معمولاً بهصورت 4-bit کوانتیزه شدهاند. به همین دلیل، یک مدل 7B یا 8B بهجای 16 GB، حدود 5 GB فضای دیسک مصرف میکند. کوانتیزهسازی استنتاج روی CPU را اساساً ممکن میکند.
Runner آن بر پایه llama.cpp ساخته شده است؛ کتابخانه استنتاج C++ که کوانتیزهسازی GGUF را روی سختافزار معمولی عملی کرد. Ollama از آن زمان برای برخی خانوادههای مدل جدیدتر، engine اختصاصی خود را نیز اضافه کرده است؛ اما llama.cpp همچنان زیربنای بیشتر مدلهایی است که این ابزار ارائه میکند. بنابراین، وقتی افراد Ollama را با llama.cpp مقایسه میکنند، در بیشتر موارد یک لایه ارگونومی را با ابزاری مقایسه میکنند که Ollama آن را پوشش میدهد.
هدف طراحی این ابزار، استفاده توسط یک کاربر است. تا ژوئیه 2026، مقدار پیشفرض OLLAMA_NUM_PARALLEL برابر با 1 است. این مقدار یعنی یک مدل در هر لحظه فقط یک درخواست را پردازش میکند و همه درخواستهای دیگر در صفی قرار میگیرند که بهصورت پیشفرض 512 ورودی دارد (OLLAMA_MAX_QUEUE). میتوانید مقدار تنظیمات اجرای موازی را افزایش دهید؛ بخش زیر هزینه این کار را توضیح میدهد. اگر تاکنون Ollama را اجرا نکردهاید، کار را با میزبانی Ollama روی یک VPS و بسته نگهداشتن پورت 11434 شروع کنید، زیرا API هیچ نوع احراز هویتی ندارد.
vLLM واقعاً چیست
vLLM یک سرور inference و هیچ چیز دیگری نیست. این ابزار یک کتابخانه مدل را مدیریت نمیکند، prompt چت ندارد و هنگام دریافت درخواست، مدلی را برای شما دریافت نمیکند. هنگام راهاندازی، یک repository در Hugging Face را مشخص میکنید؛ vLLM همان یک مدل را بارگیری میکند و تا زمانی که فرایند را متوقف کنید، آن را ارائه میدهد.
نتیجه این محدودبودن، throughput است. دو سازوکار این کار را انجام میدهند. PagedAttention، KV cache (کش key-value؛ وضعیت attention مربوط به هر token که مدل برای هر درخواست فعال نگه میدارد) را در blockهایی با اندازه ثابت ذخیره میکند؛ مشابه شیوهای که سیستمعامل حافظه را page میکند. در نتیجه، درخواست دیگر به یک رزرو بزرگ و پیوسته، متناسب با بدترین حالت، نیاز ندارد. بنابراین حافظهای که قبلاً رزرو اما بدون استفاده میماند، برای درخواستهای همزمان بیشتر در دسترس قرار میگیرد. Continuous batching به یک درخواست جدید اجازه میدهد در مرحله بعدی decoding به batch در حال اجرا بپیوندد، نه اینکه تا پایان batch فعلی منتظر بماند. یک sequence که کارش تمام شده است، بلافاصله batch را ترک میکند و slot آن دوباره پر میشود.
نتیجه عملی این است: روی یک GPU، افزایش تعداد کاربران همزمان از 1 به 30، مجموع tokenها در هر ثانیه را بهطور چشمگیری افزایش میدهد، در حالی که سرعت هر کاربر بسیار کمتر از حد انتظار کاهش مییابد. در حالت پیشفرض Ollama، افزایش تعداد کاربران از 1 به 30 فقط باعث میشود 29 نفر منتظر بمانند.
دستهبندی پیوسته تفاوت اصلی را ایجاد میکند
پنج درخواست را تصور کنید که در یک لحظه و روی سختافزار یکسان به هر سرور ارسال میشوند.
Ollama با تنظیمات پیشفرض، درخواست اول را تا پایان اجرا میکند، سپس درخواست دوم را، و به همین ترتیب ادامه میدهد. پنجمین درخواستدهنده باید منتظر 4 تولید کامل بماند. توان عملیاتی کلی تقریباً برابر با سرعت یک تولید است، زیرا پردازنده در هر لحظه فقط روی یک دنباله کار میکند.
vLLM هر 5 دنباله را در همان گذر روبهجلو رمزگشایی میکند. تولید 1 توکن برای 5 دنباله، فقط اندکی بیشتر از تولید 1 توکن برای 1 دنباله هزینه دارد؛ زیرا بخش پرهزینه، خواندن وزنهای مدل از حافظه است و این خواندن در کل دسته بهصورت مشترک انجام میشود. همین واقعیت درباره پهنایباند حافظه است که استنتاج روی CPU را کند میکند: هزینه اصلی انتقال وزنها است، نه انجام محاسبات.
میتوانید OLLAMA_NUM_PARALLEL=4 را تنظیم کنید و بخشی از این قابلیت را بهدست آورید. هزینه این کار، مصرف حافظه است. هر شکاف موازی به KV cache اختصاصی خود نیاز دارد و Ollama پنجره زمینه را میان شکافها تقسیم میکند. بنابراین، 4 درخواست موازی در برابر مدلی که برای 8192 توکن پیکربندی شده است، برای هر درخواست 2048 توکن زمینه باقی میگذارد. cache صفحهبندیشده vLLM از این مصالحه جلوگیری میکند، زیرا بلوکها همزمان با رشد واقعی درخواست، به آن اختصاص مییابند.
نصب و ارائه سرویس با Ollama
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.1:8b
ollama run --verbose llama3.1:8b "Write two sentences about Linux."اسکریپت نصب یک کاربر سیستمی ollama ایجاد میکند، باینری را نصب میکند و سرویس ollama.service را ثبت میکند که به 127.0.0.1:11434 متصل است. خط eval rate که --verbose چاپ میکند، تعداد واقعی توکن بر ثانیه روی آن سامانه است. این مقدار را به هر رقم منتشرشده ترجیح دهید.
برای افزایش همزمانی، از یک drop-in برای systemd استفاده کنید تا ارتقا این تغییر را بازنویسی نکند:
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_KEEP_ALIVE=30m"sudo systemctl restart ollama
ollama psollama ps موارد بارگذاریشده را نشان میدهد و ستون PROCESSOR آن مقدار واقعی را مشخص میکند. 100% CPU یعنی هیچ GPUای درگیر نیست؛ این توضیح واقعیِ بیشتر گزارشها درباره کند بودن Ollama است.
نصب و ارائه با vLLM
vLLM به Linux و Python 3.10 تا 3.13 نیاز دارد. آن را در محیط مجازی اختصاصی خود نصب کنید، زیرا یک build مشخص از PyTorch را نصب میکند:
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --torch-backend=autoسپس یک مدل را ارائه کنید. نام مدل، شناسه مخزن در Hugging Face است، نه یک برچسب کوتاه:
vllm serve Qwen/Qwen2.5-1.5B-Instructراهاندازی در بار اول کند است، زیرا ابتدا وزنها را دانلود میکند و سپس GPU را برای تعیین تعداد بلوکهای KV cache قابل جایگیری، profile میکند. سرویس روی port 8000 به درخواستها گوش میدهد. پیش از نوشتن کد client، آن را بررسی کنید:
curl http://localhost:8000/v1/models
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "Qwen/Qwen2.5-1.5B-Instruct", "messages": [{"role": "user", "content": "Who won the world series in 2020?"}]}'اگر Docker از قبل روی سیستم نصب است، image رسمی، نیاز به انجام کارهای مربوط به وابستگی CUDA را برطرف میکند:
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
--env "HF_TOKEN=$HF_TOKEN" \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model Qwen/Qwen3-0.6B--ipc=host ضروری است و جنبه تزئینی ندارد: PyTorch tensorها را از طریق shared memory بین processها جابهجا میکند و مقدار پیشفرض shared memory در Docker برای inference با tensor-parallel بسیار کم است.
مهمترین flagها در محیط production عبارتاند از --max-model-len (اندازه پنجره context که مایل به پرداخت هزینه آن هستید)، --gpu-memory-utilization (سهمی از حافظه card که vLLM مجاز است استفاده کند؛ این مقدار تا July 2026 بهطور پیشفرض 0.92 است)، --tensor-parallel-size برای تقسیم یک مدل بین چند GPU، و --api-key.
احراز هویت در vLLM با یک flag فعال میشود و در Ollama وجود ندارد
vLLM در صورت ارائه توکن، استفاده از bearer token را الزامی میکند:
vllm serve Qwen/Qwen2.5-1.5B-Instruct --api-key token-abc123همین مقدار میتواند از متغیر محیطی VLLM_API_KEY نیز دریافت شود. درخواست بدون این مقدار، پاسخ HTTP 401 دریافت میکند. بااینحال، این موضوع همچنان دلیلی برای انتشار port 8000 روی یک رابط عمومی نیست؛ زیرا vLLM قابلیت rate limiting ندارد و توکن در یک اتصال plain HTTP هنگام انتقال قابل خواندن است. البته این موضوع نشان میدهد که سرور مفهومی از درخواستکننده دارد.
Ollama هیچ سازوکار احراز هویتی ندارد. هیچ key، login یا allow-list وجود ندارد. هر فرایندی که بتواند به 11434 دسترسی پیدا کند، میتواند مدلها را اجرا، دریافت یا حذف کند. سرویس را روی loopback نگه دارید و از طریق یک WireGuard VPN که خودتان میزبانی میکنید، یا از طریق یک reverse proxy دارای احراز هویت که TLS (امنیت لایه انتقال) را خاتمه میدهد، به آن دسترسی پیدا کنید.
سختافزار: هرکدام به چه چیزی نیاز دارند
Ollama روی CPU اجرا میشود. یک مدل quantized چهاربیتی، بهازای هر میلیارد پارامتر، تقریباً نیم گیگابایت RAM مصرف میکند و حدود 1 گیگابایت سربار زمان اجرا، بهاضافه حافظه بیشتر برای context، نیاز دارد. بنابراین یک مدل 3B به حدود 4 GB حافظه آزاد و یک مدل 8B به حدود 8 GB نیاز دارد. سرعت روی vCPU اشتراکی از چند توکن تا اعداد پایین دورقمی توکن در ثانیه است. علت این وضعیت پهنایباند حافظه است، نه پیکربندی نادرست؛ هیچ flagی آن را اصلاح نمیکند.
vLLM یک GPU را پیشفرض میگیرد. مسیر پیشفرض آن، weightهای unquantized را با دقت 16-bit ارائه میکند. این مقدار تقریباً بهازای هر میلیارد پارامتر 2 GB است؛ بنابراین یک مدل 8B فقط برای weightها، پیش از KV cache که برای همزمانی موردنیاز اجرای vLLM نصب کردهاید، حدود 16 GB حافظه ویدئویی نیاز دارد. روی یک کارت 24 GB، فضای قابلاستفادهای برای cache باقی میماند. روی کارت 16 GB چنین فضایی وجود ندارد؛ بنابراین یا باید مدل کوچکتری انتخاب کنید، یا --quantization را همراه با یک checkpoint کوانتیده ارسال کنید. backend مربوط به CPU وجود دارد، اما wheelهای استاندارد برای آن ساخته نشدهاند و استفاده از آن، دلیل اصلی اجرای vLLM را از بین میبرد.
بنابراین، پرسش درباره سختافزار در بیشتر موارد پاسخ پرسش درباره نرمافزار را نیز مشخص میکند. اگر GPU ندارید، از Ollama استفاده کنید. اگر یک GPU اجارهای دارید که بهدلیل سریالیشدن درخواستها فقط 5 درصد utilization دارد، از vLLM استفاده کنید.
کدام گزینه برای بار کاری شما مناسب است
- یک کاربر، یک CPU VPS، و کارهای تهیه پیشنویس و خلاصهسازی: Ollama. سرعت آن قابلقبول است و گزینه سادهتری وجود ندارد.
- یک دستیار کدنویسی یا یک MCP server که ابزارهای شما را به یک مدل محلی متصل میکند و فقط شما آن را فراخوانی میکنید: Ollama. همزمانی برابر با 1، بار کاری واقعی شماست.
- مقایسه 5 مدل در این هفته: Ollama. دریافت و حذف مدلهای دارای برچسب دقیقاً کاری است که Ollama برای آن مناسب است، درحالیکه vLLM برای هر مدل به راهاندازی مجدد فرایند نیاز دارد.
- یک برنامه داخلی، یک محصول گفتوگومحور یا یک خط لوله بازیابی با کاربران واقعی: vLLM. در این شرایط، batching هزینه GPU را توجیه میکند.
- یک کار دستهای برای امتیازدهی به 100000 سند در طول شب: vLLM، با
--max-num-seqsبالا. توان عملیاتی تنها معیار مهم است و تأخیر هر سند اهمیتی ندارد. - یک پلتفرم agent که چندین agent هوش مصنوعی خودمیزبان بهطور همزمان به مدل دسترسی دارند: vLLM، زیرا ترافیک agent ذاتاً انفجاری و موازی است.
حالتهای خرابی و رشتههایی که مشاهده خواهید کرد
vLLM با خطای KV cache از شروع به کار خودداری میکند. این پیام هر دو عدد را نشان میدهد:
ValueError: The model's max seq len (32768) is larger than the maximum number of tokens that can be stored in KV cache (8192). Try increasing gpu_memory_utilization or decreasing max_model_len when initializing the engine.مدل پنجره زمینهای بزرگتر از حافظه باقیمانده پس از بارگذاری وزنها اعلام میکند. مقدار آن را با --max-model-len 8192 کاهش دهید، یا اگر فرایند دیگری از کارت استفاده نمیکند، مقدار --gpu-memory-utilization را افزایش دهید. افزایش میزان استفاده به بیش از حدود 0.95 معمولاً این خطای راهاندازی را به خطای CUDA out-of-memory در زمان بار کاری تبدیل میکند که حالت نامطلوبتری است.
Ollama در میانه تولید، Killed را چاپ میکند. Linux out-of-memory killer فرایند را متوقف کرده است، زیرا مدل به RAM بیشتری از ظرفیت سیستم نیاز داشته است. با sudo dmesg | grep -i oom این موضوع را تأیید کنید. راهحل، استفاده از مدلی کوچکتر یا مدلی با quantization بیشتر است، نه تغییر یک تنظیم.
Ollama بهتنهایی پاسخها را بهدرستی تولید میکند، اما تحت بار متوقف میشود. هیچ خطایی در هیچجا نمایش داده نمیشود. درخواستها با افزایش تعداد فراخوانیکنندگان، صرفاً زمان بیشتری میبرند، زیرا OLLAMA_NUM_PARALLEL=1 آنها را بهصورت سریالی پردازش میکند. مقدار آن را افزایش دهید و کاهش context هر درخواست را بپذیرید، یا بار کاری را به vLLM منتقل کنید.
vLLM در هر فراخوانی، 401 برمیگرداند. آن را با --api-key اجرا کردهاید، اما کلاینت هیچ headerای با نام Authorization ارسال نمیکند. بیشتر کتابخانههای کلاینت OpenAI هر مقداری را که بهعنوان کلید ارسال کنید، استفاده میکنند؛ بنابراین مقدار را در همانجا تنظیم کنید و flag را حذف نکنید.
vLLM اعلام میکند که مدل پیدا نشد. Ollama مدلها را در صورت نیاز دریافت میکند، اما vLLM این کار را انجام نمیدهد. فیلد model در بدنه درخواست باید با repository idای که با آن اجرا کردهاید مطابقت داشته باشد، یا با مقدار --served-model-name در صورتی که آن را تنظیم کرده باشید. رشته دقیق را با curl http://localhost:8000/v1/models تأیید کنید.
اجرای هر دو گزینه، پاسخی منطقی است
این دو گزینه جایگزین انحصاری یکدیگر نیستند. یک الگوی رایج این است که vLLM روی یک نمونه GPU اجرای برنامه را ارائه دهد و Ollama در کنار آن، روی VPS معمولی، برای اسکریپتهای محلی، کارهای cron و آزمایش انتشارهای جدید مدل استفاده شود. هر دو endpoint با OpenAI سازگار هستند؛ بنابراین یک کتابخانه کلاینت و تغییر base-URL برای استفاده از هر دو کافی است. کنترل هزینه در اینجا از انتخاب هر یک از این موتورهای اجرا اهمیت بیشتری دارد، زیرا یک GPU بیکار همان هزینه یک GPU مشغول را دارد و قابلپیشبینی نگهداشتن هزینههای عامل و استنتاج حوزهای جدا از انتخاب سرور است.
FAQ
آیا vLLM از Ollama سریعتر است؟
برای یک درخواست روی همان GPU، اختلاف سرعت اندک است؛ زیرا هر دو محاسبات یکسانی انجام میدهند. برای درخواستهای همزمان متعدد، vLLM عملکرد بسیار بهتری دارد؛ زیرا batching پیوسته، هر توالی فعال را در یک forward pass رمزگشایی میکند، درحالیکه تنظیم پیشفرض Ollama آنها را یکییکی اجرا میکند. در ماشینی که فقط CPU دارد، این پرسش کاربردی ندارد: Ollama روی چنین سیستمی اجرا میشود، اما vLLM عملاً اجرا نمیشود.
آیا vLLM بدون GPU اجرا میشود؟
بهصورت کاربردی خیر. wheelهای استاندارد برای GPUهای NVIDIA یا AMD تهیه شدهاند و مزیت اصلی vLLM، یعنی استفاده کامل از شتابدهنده با درخواستهای دستهای، روی CPU از بین میرود. یک backend برای CPU و کارهای توسعه وجود دارد. برای inference واقعی روی CPU، مستقیماً از Ollama یا llama.cpp استفاده کنید.
تفاوت Ollama و llama.cpp چیست؟
llama.cpp کتابخانه inference است و GGUF قالب وزنهای quantized آن محسوب میشود. runner در Ollama بر پایه آن ساخته شده و بخشهایی را اضافه میکند که llama.cpp بر عهده شما میگذارد: model registry، دانلود خودکار، یک سرور resident، یک systemd unit و یک endpoint سازگار با OpenAI. Ollama برای برخی خانوادههای مدل جدیدتر، engine اختصاصی خود را نیز اضافه کرده است؛ بنابراین این دو دیگر در لایه زیرین کاملاً یکسان نیستند.
vLLM برای یک مدل 8B به چه مقدار حافظه GPU نیاز دارد؟
در دقت 16-bit، وزنها بهتنهایی حدود 16 GB فضا میگیرند؛ یعنی تقریباً 2 GB به ازای هر میلیارد پارامتر. KV cache نیز به فضای اضافی نیاز دارد. کارت 24 GB فضای مناسبی فراهم میکند. کارت 16 GB به یک checkpoint quantized یا مدلی کوچکتر نیاز دارد. vLLM کسری از حافظه کارت را که با --gpu-memory-utilization تعیین میشود، مطالبه میکند؛ این مقدار تا July 2026 بهطور پیشفرض 0.92 است.
آیا برای جابهجایی بین این دو باید کد برنامهام را تغییر دهم؟
معمولاً فقط باید base URL، API key و نام مدل را تغییر دهید. Ollama رابط سازگار با OpenAI خود را در http://127.0.0.1:11434/v1 ارائه میکند و key را نادیده میگیرد، درحالیکه vLLM رابط خود را در http://localhost:8000/v1 ارائه میکند و اگر key تعیین کنید، آن را الزامی میکند. نام مدلها نیز از نظر قالب متفاوتاند: llama3.1:8b برای Ollama و یک repository id کامل، مانند Qwen/Qwen2.5-1.5B-Instruct، برای vLLM.