Разбираем, как запустить Llama 2 7B в Docker на DigitalOcean с FastAPI API. Реальная смета, пошаговые команды и советы по безопасности.— Читать дальше «Llama 2 на DigitalOcean за $12: self-hosting гид»
Плата за OpenAI API для небольшого pet-проекта легко переваливает за несколько сотен долларов в месяц. Альтернатива — развернуть открытую языковую модель самостоятельно и платить только за виртуальный сервер. В этом гайде разбираем, как запустить Llama 2 7B в собственном Docker-контейнере на DigitalOcean и получить production-ready HTTP API меньше чем за 15 минут работы с терминалом.
Автор оригинального руководства указывает заголовок «за $5/месяц», но на практике минимально жизнеспособная конфигурация обходится в $6–12/месяц. За $5 дроплет даёт всего 1 ГБ ОЗУ — для семимиллиардной модели этого катастрофически мало. Ниже — реальные цифры и честная смета.
Llama 2 — семейство открытых больших языковых моделей от Meta. Версия 7B содержит 7 миллиардов параметров, понимает английский и ряд других языков, умеет писать код, отвечать на вопросы и дополнять текст. Лицензия разрешает коммерческое использование при соблюдении простых правил, а веса можно скачать с Hugging Face.
Self-hosting в данном случае означает, что вы сами устанавливаете модель на арендованный сервер, контролируете окружение, не делитесь данными пользователей с третьими лицами и не зависите от чужих rate limit. Главная экономика: при интенсивном использовании собственный инференс обходится в десятки раз дешевле облачных API.
Ключевые выводы
Российская специфика: сайт DigitalOcean периодически попадает под блокировки Роскомнадзора. Для регистрации и управления Droplet может понадобиться VPN. Альтернативы — Hetzner, Selectel, Yandex Cloud или другие европейские и российские провайдеры; логика развёртывания от этого почти не меняется.Шаг 1. Создаём Droplet и подключаемся по SSH
В панели DigitalOcean нажимаем Create → Droplet. Выбираем ближайший к целевой аудитории регион — для России это обычно Франкфурт или Амстердам. В качестве образа указываем Ubuntu 22.04 x64, тип — Basic Shared CPU, конфигурацию — 2 vCPU / 4 ГБ RAM. Авторизацию настраиваем через SSH-ключ, парольный вход отключаем.
Сгенерировать ключ и подключиться можно так:
ssh-keygen -t ed25519 -C "llama-deployment" -f ~/.ssh/llama_do
ssh -i ~/.ssh/llama_do root@YOUR_DROPLET_IP
После подключения обновляем пакеты и ставим Docker официальным скриптом. Добавляем root в группу docker, чтобы не писать sudo перед каждой командой.
apt update && apt upgrade -y
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
usermod -aG docker root
docker run hello-world
apt install -y git curl wget htop python3-pip
mkdir -p /opt/llama2-api && cd /opt/llama2-api
Приложение состоит из трёх файлов: Dockerfile, requirements.txt и app.py. Ключевой трюк — CPU-версия PyTorch и библиотека bitsandbytes, которая позволяет загрузить 7-миллиардную модель в 4 ГБ видеопамяти/ОЗУ.
FROM python:3.10-slim-bullseye
WORKDIR /app
RUN apt-get update && apt-get install -y \
build-essential curl git \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
RUN mkdir -p /app/models
ARG HF_TOKEN
ENV HF_TOKEN=${HF_TOKEN}
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
fastapi==0.104.1
uvicorn==0.24.0
pydantic==2.5.0
torch==2.1.1 --index-url https://download.pytorch.org/whl/cpu
transformers==4.35.2
bitsandbytes==0.41.1
accelerate==0.25.0
peft==0.7.1
Приложение загружает модель при старте, кэширует её в /app/models и предоставляет три endpoint: /health, /info и /generate. Квантование в 4 бита снижает точность незначительно, но уменьшает потребление памяти в 3–4 раза.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import torch, time, logging
from contextlib import asynccontextmanager
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
model = None
tokenizer = None
class GenerationRequest(BaseModel):
prompt: str
max_tokens: int = 256
temperature: float = 0.7
top_p: float = 0.9
top_k: int = 50
@asynccontextmanager
async def lifespan(app: FastAPI):
global model, tokenizer
logger.info("Loading model...")
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16
)
tokenizer = AutoTokenizer.from_pretrained(
"meta-llama/Llama-2-7b-hf", cache_dir="/app/models")
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantization_config=bnb_config,
device_map="auto",
cache_dir="/app/models",
torch_dtype=torch.bfloat16
)
logger.info("Model loaded")
yield
del model, tokenizer
app = FastAPI(title="Llama 2 API", version="1.0.0", lifespan=lifespan)
@app.get("/health")
async def health():
return {"status": "healthy", "model_loaded": model is not None}
@app.post("/generate")
async def generate(request: GenerationRequest):
if model is None or tokenizer is None:
raise HTTPException(status_code=503, detail="Model not loaded")
inputs = tokenizer(request.prompt, return_tensors="pt", truncation=True, max_length=512)
start = time.time()
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=request.max_tokens,
temperature=request.temperature,
top_p=request.top_p,
top_k=request.top_k,
do_sample=True,
pad_token_id=tokenizer.eos_token_id,
attention_mask=inputs.attention_mask
)
inference_time = time.time() - start
generated_text = tokenizer.decode(
outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
return {
"prompt": request.prompt,
"generated_text": generated_text,
"tokens_generated": outputs[0].shape[0] - inputs.input_ids.shape[1],
"inference_time": inference_time
}
Создаём файл с токеном Hugging Face. Никогда не коммитьте его в репозиторий: в продакшене используйте переменные окружения или секрет-менеджер.
echo 'HF_TOKEN=hf_ВАШ_ТОКЕН' > /opt/llama2-api/.env
Первый запуск занимает 10–15 минут: скачиваются зависимости PyTorch и веса модели. Чтобы не качать веса при каждом перезапуске, подключаем Docker volume.
cd /opt/llama2-api
docker build \
--build-arg HF_TOKEN=$(grep HF_TOKEN .env | cut -d '=' -f2) \
-t llama2-api:latest .
Для удобного управления добавляем docker-compose.yml:
version: '3.8'
services:
llama2-api:
image: llama2-api:latest
container_name: llama2-api
ports:
- "8000:8000"
volumes:
- llama-models:/app/models
environment:
- HF_TOKEN=${HF_TOKEN}
restart: unless-stopped
deploy:
resources:
limits:
memory: 3.5G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
volumes:
llama-models:
driver: local
export HF_TOKEN=$(grep HF_TOKEN .env | cut -d '=' -f2)
docker compose up -d
docker logs -f llama2-api
Когда в логах появится Uvicorn running on http://0.0.0.0:8000, тестируем endpoint'ы:
curl http://localhost:8000/health
curl http://localhost:8000/info
curl -X POST http://localhost:8000/generate \
-H "Content-Type: application/json" \
-d '{"prompt": "The future of AI is", "max_tokens": 100}'
Ответ должен содержать сгенерированный текст, количество токенов и время инференса. На CPU одна генерация из 100 токенов занимает 4–10 секунд — это нормально для бюджетного дроплета.
Шаг 7. Безопасно выводим API в интернетОткрывать порт 8000 напрямую в интернет небезопасно. Ставим Nginx как reverse proxy, настраиваем HTTPS через Let's Encrypt и базовую аутентификацию. Для rate limiting используем limit_req в Nginx или облачный firewall DigitalOcean.
apt install -y nginx certbot python3-certbot-nginx
systemctl enable --now nginx
Минимальная конфигурация Nginx выглядит так:
server {
listen 443 ssl http2;
server_name llama.example.com;
ssl_certificate /etc/letsencrypt/live/llama.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/llama.example.com/privkey.pem;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
limit_req zone=api burst=10 nodelay;
}
}
server {
listen 80;
server_name llama.example.com;
return 301 https://$host$request_uri;
}
Про безопасность: Llama 2 — мощная модель, способная генерировать вредоносные инструкции, персональные данные или нежелательный контент. Не выставляйте публичный API без аутентификации, логируйте запросы и рассмотрите фильтрацию промптов на уровне приложения.
Часто задаваемые вопросы
1
Можно ли обойтись дроплетом за $5?
Нет. 1 ГБ ОЗУ не хватит даже для загрузки 4-битной Llama 2 7B. Минимально жизнеспособная конфигурация — 2 ГБ ОЗУ, рекомендуемая — 4 ГБ. Автор оригинала использует $12/месяц Droplet, и это честная цифра для стабильной работы.
2
Нужна ли видеокарта?
Нет. Гайд рассчитан на CPU-инференс. GPU ускорит генерацию в разы, но DigitalOcean Droplets с GPU стоят значительно дороже и для экспериментов не нужны.
3
Какая скорость генерации?
На 2-vCPU дроплете DigitalOcean генерация 100 токенов занимает 4–10 секунд. Для неинтерактивных задач — обработка текстов, пакетная генерация — этого достаточно.
4
Как загрузить веса Llama 2?
Нужен аккаунт Hugging Face, принятая лицензия на репозиторий meta-llama/Llama-2-7b-hf и персональный токен. Приложение скачивает веса автоматически при первом запуске.
5
Можно ли использовать российские облака?
Да. Конфигурация Docker-контейнера не привязана к провайдеру. Главное — достаточно RAM и доступ к Hugging Face/Hugging Face mirror для скачивания весов.
Self-hosted Llama 2 — рабочий способ снизить затраты на генеративный ИИ в pet-проектах и прототипах. При правильном квантовании семимиллиардная модель помещается в бюджетный дроплет, а Docker + FastAPI превращают развёртывание в рутинную процедуру. Главное — не экономить на RAM и не забывать про безопасность публичного API.
Собственный инференс — не волшебная кнопка, а инструмент с чёткой областью применения: он выигрывает там, где важны предсказуемость расходов, приватность данных и отсутствие лимитов.
Антон К.,SRE в облачном провайдере
Если соберётесь повторить гайд, начните с $12 Droplet и протестируйте нагрузку вручную. А если DigitalOcean недоступен — переносите тот же Docker Compose на Hetzner, Selectel или Yandex Cloud без изменения кода.
Источник: How to Deploy Llama 2 on DigitalOcean for $5/Month: Complete Self-Hosting Guide — RamosAI, Dev.to.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | GPU-серверы для LLM-инференса: 5 решений, на чём запустить локально в 2026 году | 0 | 20.21 | 26-08-2026 |
| 2 | Fine-tuning LLM в 2026: гид по LoRA, QLoRA и полному дообучению | 0 | 7 | 25-06-2026 |
| 3 | Ваши open source-контрибьюторы теперь ИИ-first. Как не утонуть в потоке агентских пулреквестов | 0 | 11.9 | 19-08-2026 |
| 4 | Как выбрать фреймворк для ИИ-агентов | 0 | 15 | 24-08-2026 |
| 5 | Как ограничить расходы на OpenAI API, чтобы ИИ-агенты не сожгли бюджет | 0 | 8 | 04-07-2026 |
| 6 | Kubernetes на практике: гайды и малоизвестные Open Source-инструменты | 0 | 11.88 | 25-08-2026 |
| 7 | Как мы сделали AI code review через Ollama без облака? | 0 | 6.97 | 06-03-2026 |
| 8 | Собственная облачная LLM на 16 ГБ VRAM — часть 1: базовая сборка, tools и MCP | -1 | 14.47 | 09-03-2026 |
| 9 | Monitor LLM routing with the Kubernetes Inference Extension | 0 | 8.23 | 29-05-2026 |