Проблема: 14B параметров и 6 ГБ памяти. Не сходится?
Qwen2.5-coder-14B - отличная модель для кода. Она понимает контекст, пишет без глупостей, иногда даже предлагает решения, от которых мурашки по коже. Но есть нюанс: для работы в FP16 ей нужно около 28 ГБ памяти. Даже в 4-битном квантовании - 7-8 ГБ. А у Jetson Orin Nano (самая доступная версия) - всего 4 или 8 ГБ общей памяти. Не вариант.
Покупать RTX 4090? 200+ тысяч рублей. Серверную карту A100? Полмиллиона минимум. А если хочется что-то энергоэффективное, тихое, и чтобы несколько моделей одновременно?
Типичная ошибка: пытаться запихнуть модель в одну плату через swap или zram. Получите 0.1 токена в секунду и грелку для кофе. На Orin Nano память LPDDR5 - быстрая, но ширина шины не та. Пропускная способность против GDDR6X - как велосипед против Ferrari.
Почему Orin Nano? Дешёвый AI-зоопарк
Один Orin Nano 8GB стоит около 45-50 тысяч рублей (на начало 2026). Потребляет 7-15 ватт. Три штуки - 150 тысяч, 30-40 ватт суммарно. Одна RTX 4060 Ti 16GB - те же 150к, но 160 ватт и один устройство. Если одна сгорит - система продолжает работать на двух. Кластер из трёх Nano даёт 24 ГБ общей памяти (из них 18-20 доступно после системы).
Архитектура ARM здесь не недостаток, а преимущество. Компилируем llama.cpp под aarch64 с NEON - работает идеально. Docker-образы NVIDIA готовы. Питание от USB-C PD. Размеры - как пачка сигарет.
Архитектура: три нано-борда, один RPC-сервер
Система выглядит так:
| Устройство | Роль | Память под модель | Сеть |
|---|---|---|---|
| Jetson Orin Nano #1 | RPC-сервер, слой 0-33% | ~2.5 ГБ | 2.5 GbE через USB-адаптер |
| Jetson Orin Nano #2 | RPC-клиент, слой 34-66% | ~2.5 ГБ | 2.5 GbE через USB-адаптер |
| Jetson Orin Nano #3 | RPC-клиент, слой 67-100% | ~2.5 ГБ | 2.5 GbE через USB-адаптер |
Сеть - критически важна. Встроенный гигабит на Orin Nano - достаточно, но 2.5 GbE даёт запас. Используем USB-адаптеры Realtek RTL8156 (около 2000 рублей за штуку). Коммутатор 2.5 GbE - от 4000 рублей. Или можно сделать точку-точку, если устройств всего два.
1 Подготовка железа: прошивка, сеть, охлаждение
Сначала прошиваем каждую плату актуальным JetPack 6.0 (на январь 2026 это самая свежая версия). NVIDIA обновила драйверы для Orin, добавили поддержку новых функций CUDA.
# На хосте (x86) с установленным SDK Manager
# Выбираем JetPack 6.0, Orin Nano 8GB
# Прошиваем через USB-C порт на плате
# Ждём 20-30 минут на каждую плату
# После загрузки проверяем
sudo apt update
sudo apt full-upgrade -y
nvidia-smi # Должна показать Orin
Сеть настраиваем статическими IP. Почему не DHCP? Потому что при перезагрузке устройства могут поменять адреса, и RPC сломается. В файл /etc/netplan/01-netcfg.yaml на каждом устройстве:
network:
version: 2
ethernets:
eth0: # Встроенный порт
dhcp4: true
enx001122334455: # USB-адаптер 2.5 GbE
dhcp4: no
addresses: [192.168.100.101/24] # Для первой платы
# 192.168.100.102 для второй
# 192.168.100.103 для третьей
routes:
- to: default
via: 192.168.100.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
Охлаждение. Orin Nano без радиатора троттлит через 2-3 минуты под нагрузкой. Ставьте хотя бы пассивные радиаторы (500 рублей за штуку). Идеально - маленькие вентиляторы 5V.
2 Компиляция llama.cpp с RPC поддержкой
llama.cpp на январь 2026 - версия 0.15.0. В ней улучшили поддержку RPC, добавили batched inference для распределённых систем. Компилируем на каждой плате:
# Устанавливаем зависимости
sudo apt install -y build-essential cmake git
# Для CUDA (уже есть в JetPack)
export CUDA_PATH=/usr/local/cuda
export PATH=$CUDA_PATH/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_PATH/lib64:$LD_LIBRARY_PATH
# Клонируем репозиторий
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
git checkout v0.15.0 # Актуальная версия на 25.01.2026
# Компилируем с поддержкой CUDA и RPC
mkdir build && cd build
cmake .. -DLLAMA_CUDA=ON -DLLAMA_RPC=ON -DCMAKE_BUILD_TYPE=Release
make -j$(nproc) llama llama-server
# Проверяем
./bin/llama --help | grep rpc # Должна быть опция --rpc
Не используйте флаг -DLLAMA_CUBLAS=ON для Orin! Это устаревший вариант для x86. На ARM с CUDA работает LLAMA_CUDA. Если скомпилируете с CUBLAS - получите ошибки линковки или падения.
3 Загрузка и квантование Qwen2.5-coder-14B
Qwen2.5-coder-14B-Instruct - лучший выбор на январь 2026 для задач кодинга. У неё улучшенный контекст 128K, понимание JSON, лучше работает с русским чем CodeLlama. Качаем на одну из плат (у которой больше всего свободного места):
# Устанавливаем huggingface-hub
pip install huggingface-hub
# Скачиваем модель
python -c "from huggingface_hub import snapshot_download; snapshot_download(repo_id='Qwen/Qwen2.5-Coder-14B-Instruct', local_dir='./Qwen2.5-Coder-14B')"
# Конвертируем в формат gguf
python ../convert-hf-to-gguf.py ./Qwen2.5-Coder-14B --outtype f16
# Квантуем в Q4_K_M (лучшее качество/размер)
./bin/llama-quantize ./Qwen2.5-Coder-14B/ggml-model-f16.gguf ./Qwen2.5-Coder-14B/ggml-model-Q4_K_M.gguf Q4_K_M
Размер после квантования: около 7.8 ГБ. Теперь копируем файл модели на все три устройства (можно через scp).
4 Настройка RPC-сервера и клиентов
На устройстве #1 запускаем RPC-сервер:
# На Jetson #1 (192.168.100.101)
cd llama.cpp/build
./bin/llama-server \
--model /path/to/ggml-model-Q4_K_M.gguf \
--host 0.0.0.0 \
--port 8080 \
--rpc \
--rpc-serve 0.0.0.0:8081 \
--n-gpu-layers 20 \
--ctx-size 4096 \
--batch-size 512 \
--threads 4 \
--rpc-workers 2
Флаги важные:
- --rpc: включаем RPC режим
- --rpc-serve: адрес для подключения клиентов
- --n-gpu-layers 20: на Orin Nano больше 20-25 слоёв на GPU не помещаются в память
- --rpc-workers 2: два потока для обработки RPC запросов
На устройствах #2 и #3 запускаем клиенты:
# На Jetson #2 (192.168.100.102)
./bin/llama \
--model /path/to/ggml-model-Q4_K_M.gguf \
--rpc \
--rpc-connect 192.168.100.101:8081 \
--rpc-id client2 \
--n-gpu-layers 20 \
--ctx-size 4096 \
--threads 4
# На Jetson #3 (192.168.100.103) то же самое, но --rpc-id client3
Сервер автоматически распределит слои модели между всеми подключёнными клиентами. Проверить, что все подключились:
# На сервере смотрим логи
curl http://192.168.100.101:8080/health
# Должен вернуть статус и список клиентов
5 Тестирование и метрики производительности
Отправляем тестовый запрос через curl или Python:
curl http://192.168.100.101:8080/completion \
-H "Content-Type: application/json" \
-d '{
"prompt": "Напиши функцию на Python, которая решает квадратное уравнение",
"n_predict": 256,
"temperature": 0.1
}'
Мои результаты на трёх Orin Nano 8GB:
| Метрика | Один Orin Nano | Три Orin Nano через RPC | RTX 4060 Ti 16GB |
|---|---|---|---|
| Токенов/сек (первые 256) | 1.2-1.5 | 4.8-5.3 | 12-15 |
| Потребление (ватт) | 12-14 | 35-42 | 160-180 |
| Токенов/ватт | ~0.1 | ~0.13 | ~0.08 |
| Задержка первого токена (мс) | 1200 | 1800-2200 | 800 |
Видно главное: RPC добавляет задержку (данные ходят по сети), но общая пропускная способность вырастает почти в 4 раза. По энергоэффективности три Orin Nano лучше, чем одна десктопная видеокарта.
Где собака зарыта: нюансы распределённого llama.cpp
1. Сеть должна быть надёжной. Если один клиент отваливается - вся инференс падает. В llama.cpp 0.15.0 нет автоматического rebalance. Придётся перезапускать.
2. Неравномерная загрузка. Первые и последние слои модели выполняются только на сервере. Средние - распределяются. Сервер становится бутылочным горлышком. Решение: использовать более сложную топологию из статьи про тестирование RPC с несколькими серверами.
3. Тепло. Три платы рядом греют друг друга. Расстояние минимум 5 см между ними. Или активное охлаждение.
4. Память. После запуска модели на каждом Orin Nano остаётся 1-1.5 ГБ свободной памяти. Этого мало для ОС. Увеличиваем swap до 8 ГБ:
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Добавить в /etc/fstab
А если хочется интерактив? WebUI и API
На сервере (Jetson #1) ставим Open WebUI или llama.cpp собственный API:
# Запускаем API сервер поверх RPC
./bin/llama-server \
--model /path/to/model.gguf \
--host 0.0.0.0 \
--port 8080 \
--rpc \
--rpc-serve 0.0.0.0:8081 \
--api
Теперь можно подключиться через Open WebUI как в гайде про 20B-модели или через прямые HTTP запросы.
Для продакшена оберните всё в systemd службы. Иначе после перезагрузки придётся запускать вручную. Пример unit-файла на GitHub llama.cpp в папке examples.
Ошибки, которые все совершают (и как их избежать)
- "Connection refused" при подключении клиентов
Проверьте iptables:sudo iptables -L. Или отключите временно:sudo iptables -F. В продакшене настройте правила правильно. - Модель загружается, но токены не генерируются
Скорее всего, не хватает памяти. Смотритеfree -hиnvidia-smi. Уменьшите--ctx-sizeили--batch-size. - Разные версии llama.cpp на сервере и клиентах
Должны быть идентичными! Иначе сериализация тензоров сломается. Компилируйте из одного коммита. - Сеть 1 GbE вместо 2.5 GbE
Будет работать, но throughput упадёт на 30-40%. Особенно заметно на больших batch.
Самая обидная ошибка: купить три Orin Nano 4GB версии. 4 ГБ недостаточно даже для клиента. Берите только 8GB версии.
Что дальше? Масштабирование и оптимизации
Можно добавить четвёртую плату как резервную (hot standby). Или использовать принципы из AI-Doomsday-Toolbox для гетерогенного кластера: Orin Nano + Raspberry Pi 5 + старый ноутбук.
Для продакшена:
- Настроить Prometheus метрики (llama.cpp умеет в /metrics)
- Добавить load balancer перед несколькими RPC-серверами
- Кэшировать эмбеддинги часто используемых промптов
И главный совет: не пытайтесь сделать из этого ChatGPT. Это инструмент для конкретных задач - код-ревью, генерация шаблонов, документация. Интерактивный диалог будет мучительным из-за задержек.
А вот пачкать 10-20 файлов автоматическими исправлениями - идеально. Запускаете ночью, утром получаете результат. Потребляет как три лампочки, стоит как одна видеокарта. Иногда простота и надёжность важнее мега-токенов в секунду.