Почему Oracle Cloud и Qwen2.5-3B — идеальный тандем для бедного DevOps
Стоимость API-вызовов к ChatGPT растёт как на дрожжах. Платформы вроде Anthropic или Google берут за токены столько, что кажется, будто они продают золотые слитки, а не вычисления. При этом у тебя есть задачи, которые не требуют GPT-4 Turbo: классификация обращений, извлечение сущностей, простой чат-бот для внутренних нужд.
Зачем платить $0.01 за запрос, если можно платить $0? В буквальном смысле.
Oracle Cloud Free Tier — это не просто песочница. Это полноценный сервер с 4 ARM-ядрами, 24GB RAM и 200GB SSD, который живёт вечно (пока ты его не удалишь). Идеально для запуска квантованных моделей через llama.cpp. Qwen2.5-3B — одна из лучших маленьких моделей на начало 2026 года. Она понимает контекст до 32k токенов, отлично справляется с кодом и английским, и при этом весит всего ~2GB в формате Q4_K_M.
Что сломается, если делать по старым гайдам 2024 года
90% туториалов в интернете устарели. Они предлагают скачивать GGUF-файлы с Hugging Face через wget, но забывают сказать, что с 2025 года репозитории моделей перешли на новую систему контроля версий. Старые прямые ссылки не работают.
Ещё одна ловушка — сборка llama.cpp. Если просто клонировать master-ветку и сделать make, получишь ошибку компиляции из-за изменений в архитектуре ARM. Нужны специфические флаги.
И самое главное — безопасность. Открывать порт 8080 без nginx и rate limiting на публичном IP — это как оставить ключи от квартиры в замочной скважине. Через час тебе начнут слать запросы боты со всего мира, а через два — сервер упадёт от нагрузки.
Пошаговый план: от регистрации до работающего API
1 Регистрируемся в Oracle Cloud (это боль, но нужно пройти)
Переходишь на страницу Free Tier. Готовь кредитную карту — они её проверяют, но не списывают деньги (если не выйдешь за лимиты).
Важно: выбирай регион с доступностью ARM-инстансов. На февраль 2026 года лучше всего работают Frankfurt, Amsterdam и Ashburn. Tokyo и Seoul часто перегружены.
После подтверждения email и карты заходишь в Console, ищешь "Compute" → "Instances" → "Create Instance".
2 Настраиваем инстанс: не повторяй эти ошибки
Здесь большинство наступает на грабли:
- Image: Ubuntu 24.04 LTS (не 22.04, там старые пакеты для CUDA, которые тебе не нужны, но конфликтуют)
- Shape: Ampere ARM, 4 OCPU, 24GB memory (это бесплатный вариант)
- SSH keys: Генерируй новую пару, не используй старые ключи. Сохрани приватный ключ — потеряешь, не войдёшь.
- Boot volume: Оставляй 200GB, но можешь уменьшить до 100GB, если планируешь только одну модель.
Самая критичная часть — Security Rules. По умолчанию открыты все порты для всех. Это убийственно.
Сразу после создания инстанса иди в "Virtual Cloud Network" → "Subnet" → "Security Lists". Создай новую политику:
# Разрешаем только SSH и наш будущий порт
Allow: TCP, Source: 0.0.0.0/0, Destination Port: 22
Allow: TCP, Source: 0.0.0.0/0, Destination Port: 443 # Будет nginx с SSL
Deny: ALL, Source: 0.0.0.0/0
3 Первый вход и базовая настройка
Подключаешься через SSH (помнишь про приватный ключ?):
ssh -i ~/.ssh/oracle_key ubuntu@ваш_публичный_ip
Первым делом — обновляем систему и ставим обязательные пакеты:
sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential cmake git python3-pip nginx
sudo apt install -y python3-virtualenv python3-venv
4 Собираем llama.cpp с правильными флагами
Вот где начинается магия. Стандартная сборка упадёт с ошибкой. Нужно явно указать архитектуру:
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
mkdir build && cd build
# Ключевые флаги для ARM Oracle Cloud
cmake .. -DCMAKE_C_FLAGS="-mcpu=native -mtune=native" \
-DCMAKE_CXX_FLAGS="-mcpu=native -mtune=native" \
-DLLAMA_NATIVE=ON \
-DLLAMA_ARM_FMA=ON \
-DLLAMA_METAL=OFF # Metal только для macOS
make -j4 # 4 ядра у нас есть
Проверяем, что всё собралось:
./bin/llama-cli --help
5 Качаем и квантуем Qwen2.5-3B (новый метод)
Старый способ с прямым скачиванием GGUF больше не работает. Используем Python-скрипт:
cd ~
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
# Устанавливаем зависимости для конвертации
pip install torch huggingface-hub transformers
# Скачиваем и конвертируем модель в GGUF
python3 convert-hf-to-gguf.py \
--model-id Qwen/Qwen2.5-3B-Instruct \
--outfile qwen2.5-3b-instruct.gguf \
--outtype q4_k_m # Лучшее качество/размер для CPU
Если скрипт не сработал (бывает с новыми моделями), есть запасной вариант через huggingface-hub:
from huggingface_hub import snapshot_download
import subprocess
# Скачиваем модель
model_path = snapshot_download(
repo_id="Qwen/Qwen2.5-3B-Instruct",
revision="main",
local_dir="./qwen2.5-3b"
)
# Конвертируем
subprocess.run([
"python3", "convert-hf-to-gguf.py",
model_path,
"--outfile", "qwen2.5-3b-instruct.gguf",
"--outtype", "q4_k_m"
])
В результате получится файл ~2GB. Переносим его в удобное место:
mkdir ~/models
mv qwen2.5-3b-instruct.gguf ~/models/
6 Запускаем сервер llama.cpp с правильными параметрами
Самый простой способ — запустить встроенный сервер llama.cpp. Но он слишком простой для продакшена. Лучше использовать отдельный бэкенд на Python с очередями запросов.
Сначала создаём виртуальное окружение:
cd ~
python3 -m venv llm-env
source llm-env/bin/activate
pip install fastapi uvicorn python-multipart requests
pip install llama-cpp-python --no-cache-dir
Создаём файл app.py:
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from llama_cpp import Llama
import os
import time
app = FastAPI(title="Qwen2.5-3B API")
# Разрешаем CORS для браузерных расширений
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
# Загружаем модель при старте
print("Loading model...")
llm = Llama(
model_path="/home/ubuntu/models/qwen2.5-3b-instruct.gguf",
n_ctx=8192, # Можно уменьшить для экономии памяти
n_threads=4, # Все ядра
n_batch=512,
verbose=False
)
print("Model loaded!")
@app.post("/generate")
async def generate_text(prompt: str, max_tokens: int = 256):
try:
start = time.time()
# Форматируем промпт для Qwen2.5-Instruct
formatted_prompt = f"<|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n"
output = llm(
formatted_prompt,
max_tokens=max_tokens,
temperature=0.7,
top_p=0.95,
echo=False
)
latency = time.time() - start
return {
"response": output['choices'][0]['text'],
"tokens": output['usage']['completion_tokens'],
"latency": round(latency, 2)
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health_check():
return {"status": "healthy", "model": "Qwen2.5-3B-Instruct-Q4_K_M"}
Запускаем сервер:
source ~/llm-env/bin/activate
uvicorn app:app --host 0.0.0.0 --port 8000 --workers 2
7 Настраиваем nginx, SSL и rate limiting
Без этого шага твой сервер сломается через день. Создаём конфиг nginx:
sudo nano /etc/nginx/sites-available/llm-api
server {
listen 443 ssl;
server_name ваш_домен_или_ip;
# Rate limiting: максимум 10 запросов в минуту с одного IP
limit_req_zone $binary_remote_addr zone=llm:10m rate=10r/m;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
location / {
limit_req zone=llm burst=5 nodelay;
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Таймауты для длинных генераций
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
# Закрываем все остальные методы, кроме нужных
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405;
}
}
Генерируем самоподписанный SSL-сертификат (для продакшена лучше использовать Let's Encrypt):
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/nginx-selfsigned.key \
-out /etc/ssl/certs/nginx-selfsigned.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=llm-server"
Активируем конфиг и перезапускаем nginx:
sudo ln -s /etc/nginx/sites-available/llm-api /etc/nginx/sites-enabled/
sudo nginx -t # Проверяем конфиг
sudo systemctl restart nginx
Реальные кейсы использования: что можно делать с этим сервером
Классификация обращений поддержки
Ты можешь настроить fine-tuning Qwen2.5 для классификации, но даже без дообучения модель справляется с базовой категоризацией. Отправляешь текст обращения, получаешь категорию: "техническая проблема", "опрос", "жалоба".
Браузерное расширение для быстрых ответов
Напиши простое расширение для Chrome, которое отправляет выделенный текст на твой сервер и получает краткий ответ. Работает полностью локально (точнее, на твоём сервере), никаких утечек данных в OpenAI.
Автоматизация рутинных задач
Настроить AI как системного администратора для простых задач: анализ логов, генерация конфигов, ответы на типовые вопросы в чате команды.
Оптимизации, которые удвоят производительность
| Параметр | Значение по умолчанию | Оптимальное значение для Oracle Cloud | Эффект |
|---|---|---|---|
| n_threads | Автоопределение | 4 | +40% скорости |
| n_batch | 512 | 1024 | Лучшая утилизация кэша |
| n_ctx | 2048 | 8192 | Поддержка длинных контекстов без перерасхода памяти |
| mlock | False | True | Предотвращает свопинг модели на диск |
Что делать, когда всё пошло не так
Сервер не запускается: "Killed"
Значит, не хватает памяти. Qwen2.5-3B в Q4_K_M занимает ~2GB, но для контекста в 8192 токенов нужно ещё ~1.5GB. Проверь, что не запущены лишние процессы:
htop # Смотри загрузку памяти
sudo systemctl stop apache2 mysql # Если были установлены
Скорость генерации 1 токен/сек
Проверь флаги компиляции llama.cpp. Возможно, не активировались оптимизации для ARM. Пересобери с флагом -DLLAMA_ARM_NEON=ON.
Модель генерирует бессмыслицу
Скорее всего, неправильно отформатирован промпт. Qwen2.5-Instruct требует специальных тегов <|im_start|> и <|im_end|>. Используй функцию format_chatml из библиотеки transformers.
А что насчёт масштабирования?
Один сервер Oracle Cloud выдержит ~5-10 одновременных пользователей. Если нужно больше — создай ещё один инстанс и поставь перед ними балансировщик нагрузки. Всё ещё бесплатно, если уложишься в лимиты.
Для серьёзных нагрузок посмотри локальную LLM-инфраструктуру на домашнем железе или бюджетный AI-сервер за $400.
Фишка: можешь развернуть несколько разных моделей на одном сервере. Qwen2.5-3B для чата, Qwen-Image-2512 (см. гайд по запуску) для анализа изображений, и какую-нибудь маленькую модель для классификации. Главное — следи за памятью.
Итог: что ты получил за 30 минут работы
- Полноценный AI-сервер с Qwen2.5-3B, который понимает 32k контекст
- REST API с rate limiting и базовой безопасностью
- Полную независимость от коммерческих API (и их ценовой политики)
- Контроль над данными — всё остаётся на твоём сервере
- Бесплатную инфраструктуру на неограниченное время
Следующий шаг — подключить этот сервер к своей CRM, чат-боту или внутреннему инструменту. Или написать браузерное расширение, которое заменит тебе ChatGPT для повседневных задач.
А самое приятное — когда коллеги спросят "Сколько ты платишь за AI API?", ты сможешь ответить: "Нисколько. У меня свой сервер".