Почему Docker-команды переводят хуже всего
Запускаете контейнер в изолированной среде без интернета? Нужно быстро перевести команду из документации, но Google Translate превращает docker run --mount type=bind,src=$(pwd),dst=/app в бессмысленный набор слов? Я тоже сталкивался с этим.
Облачные переводчики ломаются на техническом сленге, флагах командной строки, путях файлов. Особенно когда дело касается Docker — там своя логика, свои паттерны. Решение? Обучить модель понимать именно этот язык.
На 21.02.2026 Gemma 3 от Google — одна из самых сбалансированных моделей для локального запуска. Новые версии 1B и 4B специально оптимизированы для инференса на CPU и слабом железе.
Что у нас получится в итоге
CLI-утилита, которая берет английскую Docker-команду и выдает русский перевод с объяснением каждого флага. Работает полностью локально, без единого запроса в интернет. Идеально для:
- Обучения новичков Docker
- Быстрого перевода документации в офлайн-режиме
- Интеграции в CI/CD пайплайны с изолированным доступом
- Создания собственной базы знаний команд
1 Готовим датасет: какие команды и как собирать
Первая ошибка — пытаться взять все команды подряд. Docker CLI огромен, но 80% работы покрывают 20% команд. Собираем структурированный датасет:
{
"instruction": "Translate Docker command to Russian with explanations",
"input": "docker run -d --name nginx -p 8080:80 -v /data:/usr/share/nginx/html nginx:alpine",
"output": "Запустить контейнер в фоновом режиме (-d) с именем 'nginx' (--name), пробросить порт 8080 хоста на 80 контейнера (-p), подключить том с хоста /data в контейнер /usr/share/nginx/html (-v), использовать образ nginx:alpine"
}
Ключевые моменты:
- Берем реальные команды из популярных туториалов, официальной документации
- Обязательно включаем compose-файлы (docker-compose up -d)
- Добавляем команды управления сетями, томами, образами
- Для каждой команды — четкое объяснение каждого флага
Мой датасет на 21.02.2026 содержит 1250 пар «команда-объяснение». Этого достаточно для качественного финтюна даже маленькой модели.
2 Выбор модели: Gemma 3 1B против 4B — что брать
Здесь большинство ошибается дважды. Либо берут слишком большую модель (и потом мучаются со скоростью), либо слишком маленькую (и получают мусор на выходе).
| Параметр | Gemma 3 1B | Gemma 3 4B |
|---|---|---|
| Размер (4-bit) | ~0.7 GB | ~2.5 GB |
| Скорость на CPU (токенов/сек) | 45-55 | 18-25 |
| Точность в моих тестах | 76% | 94% |
| Минимальная RAM | 4 GB | 8 GB |
| Время обучения QLoRA | 25 минут | 1.5 часа |
Выбор простой: если нужна максимальная скорость на слабом железе — 1B. Если важна точность и вы готовы пожертвовать скоростью — 4B. Лично я выбрал 4B, потому что 76% точности — это когда каждая четвертая команда переводится с ошибкой. Неприемлемо для production.
Не берите Gemma 3 270B для этой задачи. Да, она умнее. Но даже в 4-bit квантовании она займет 15+ GB памяти, а скорость будет 2-3 токена в секунду на CPU. Это как стрелять из пушки по воробьям.
3 Тонкая настройка через QLoRA: настройки, которые работают
QLoRA (Quantized Low-Rank Adaptation) — это магия 2025-2026 годов. Позволяет дообучить большую модель, изменяя всего 1-2% весов. Экономия памяти в 10 раз, скорость обучения выше.
Вот конфиг, который я выбил методом проб и ошибок:
from transformers import TrainingArguments
from peft import LoraConfig
# Конфиг LoRA - не меняйте эти параметры без причины
lora_config = LoraConfig(
r=16, # Rank - увеличивать только если качество низкое
lora_alpha=32, # Alpha - обычно в 2 раза больше r
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# Параметры обучения
training_args = TrainingArguments(
output_dir="./gemma-3-4b-docker-translator",
num_train_epochs=3, # Больше 3 - overfitting гарантирован
per_device_train_batch_size=4,
gradient_accumulation_steps=2,
warmup_steps=50,
logging_steps=25,
save_steps=100,
eval_steps=100,
evaluation_strategy="steps",
learning_rate=2e-4, # Для QLoRA ставьте выше обычного
fp16=True, # Обязательно для современных GPU
gradient_checkpointing=True, # Экономит память
optim="paged_adamw_8bit", # Только так для QLoRA
report_to="none", # Отключаем wandb/tensorboard
save_total_limit=2
)
Почему именно такие параметры? r=16 — золотая середина между качеством и размером адаптера. Увеличивать до 32 или 64 стоит только если у вас огромный датасет (10k+ примеров). Для наших 1250 примеров 16 более чем достаточно.
target_modules — здесь важно не пропустить ключевые слои. В Gemma 3 архитектура немного отличается от Llama, но эти проекции работают стабильно.
4 Инференс на CPU: оптимизация скорости и памяти
Обученная модель — это только половина дела. Вторая половина — заставить ее быстро работать на обычном процессоре. Особенно если у вас нет GPU.
Используем llama.cpp — на 21.02.2026 это версия 0.16.3 с поддержкой Gemma 3 и новыми оптимизациями:
# Конвертируем модель в формат GGUF
python convert_hf_to_gguf.py \
--model ./gemma-3-4b-docker-translator \
--outfile ./gemma-3-4b-docker-translator.Q4_K_M.gguf \
--outtype q4_k_m # Лучший баланс качество/размер
# Квантование до 4-bit для экономии памяти
./quantize \
./gemma-3-4b-docker-translator.f16.gguf \
./gemma-3-4b-docker-translator.Q4_K_M.gguf \
Q4_K_M
# Запуск инференса
./main -m ./gemma-3-4b-docker-translator.Q4_K_M.gguf \
-p "Translate: docker compose down -v --rmi all" \
-n 256 \
-t 8 \
--temp 0.1 \
--repeat-penalty 1.1
Ключевые флаги для скорости:
-t 8— используем 8 потоков CPU (ставьте по количеству физических ядер)--temp 0.1— низкая температура для детерминированных переводов--repeat-penalty 1.1— штраф за повторения, чтобы модель не зацикливалась
На моем Intel i7-12700K Gemma 3 4B выдает 22-25 токенов в секунду. Для переводчика команд этого более чем достаточно — большинство команд укладываются в 50-100 токенов.
5 Создаем CLI-утилиту: обертка на Python
Работать через ./main неудобно. Создаем простую утилиту на Python:
#!/usr/bin/env python3
import subprocess
import sys
import json
class DockerTranslator:
def __init__(self, model_path: str):
self.model_path = model_path
self.template = """Translate Docker command to Russian with explanations:
Command: {command}
Translation: """
def translate(self, command: str) -> str:
prompt = self.template.format(command=command)
# Вызов llama.cpp через subprocess
cmd = [
"./main",
"-m", self.model_path,
"-p", prompt,
"-n", "256",
"-t", "8",
"--temp", "0.1",
"--repeat-penalty", "1.1",
"--silent-prompt"
]
result = subprocess.run(cmd, capture_output=True, text=True)
output = result.stdout.strip()
# Вырезаем только ответ модели
if "Translation:" in output:
translation = output.split("Translation:", 1)[1].strip()
return translation
return output
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: docker-translate 'docker run ...'")
sys.exit(1)
translator = DockerTranslator("./gemma-3-4b-docker-translator.Q4_K_M.gguf")
command = " ".join(sys.argv[1:])
result = translator.translate(command)
print(f"📦 Команда: {command}")
print(f"🇷🇺 Перевод: {result}")
Теперь работаем просто:
$ docker-translate 'docker run -it --rm ubuntu bash'
📦 Команда: docker run -it --rm ubuntu bash
🇷🇺 Перевод: Запустить интерактивный контейнер (-it) с автоматическим удалением после завершения (--rm), использовать образ ubuntu, выполнить команду bash
Тестируем: какие команды ломают модель
После обучения провел стресс-тест. 200 команд, которых не было в датасете. Результаты:
| Тип команды | Gemma 3 4B (точность) | Проблемы |
|---|---|---|
| Простые run команды | 98% | Нет |
| Сети и volumes | 92% | Иногда путает --network и --net |
| Docker Compose | 89% | Сложные флаги вроде --profile |
| Build с кэшем | 85% | --no-cache, --pull понимает не всегда |
| Swarm/Orchestration | 76% | Специфичные флаги требуют дообучения |
Вывод: модель отлично справляется с повседневными задачами. Сложные orchestration-команды требуют расширения датасета. Но для 95% разработчиков этого более чем достаточно.
Не пытайтесь заставить модель переводить команды с pipe (|) или сложной bash-логикой. Это не переводчик bash, а переводчик Docker CLI. Для сложных скриптов лучше разбивать на части.
Деплой в Docker: ирония в квадрате
Самая забавная часть — упаковываем Docker-переводчик в Docker-контейнер. Метауровень достигнут.
FROM ubuntu:22.04
# Устанавливаем зависимости для llama.cpp
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
# Клонируем и собираем llama.cpp
RUN git clone https://github.com/ggerganov/llama.cpp && \
cd llama.cpp && \
mkdir build && cd build && \
cmake .. -DLLAMA_CUBLAS=OFF && \
make -j$(nproc)
# Копируем модель и скрипты
COPY gemma-3-4b-docker-translator.Q4_K_M.gguf /app/model.gguf
COPY docker-translate.py /app/docker-translate.py
COPY entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
WORKDIR /app
ENTRYPOINT ["/app/entrypoint.sh"]
entrypoint.sh — простой скрипт, который запускает нашу утилиту:
#!/bin/bash
cd /app
python3 docker-translate.py "$@"
Собираем и запускаем:
docker build -t docker-translator .
docker run --rm docker-translator \
'docker logs --tail 100 -f container_name'
Получаем перевод команды для просмотра логов внутри контейнера, который переводит Docker-команды. Круг замкнулся.
Что делать, если хочется больше
Проект работает, но всегда есть куда расти. Вот что можно улучшить:
- Добавить контекст — модель не знает, переводите вы для новичка или для эксперта. Можно добавить префикс «Explain for beginner:» или «Brief explanation:»
- Поддержка других CLI — тот же подход работает для kubectl, git, aws-cli. Нужно только собрать датасет
- Интеграция с IDE — плагин для VS Code, который переводит команды прямо в терминале
- Обратный перевод — с русского на английский. Полезно, когда ищешь команду в документации
Самое главное — начать с малого. Не пытайтесь создать универсальный переводчик всех команд сразу. Docker CLI — отличная отправная точка: команды структурированы, документация богатая, сообщество большое.
Через неделю после запуска моего переводчика в команде из 15 разработчиков, 3 джуниора перестали задавать вопросы «что делает этот флаг?». Они просто прогоняли команду через переводчик. Экономия времени — 20-30 минут в день на человека. Умножьте на зарплату — получается существенно.
Локальные LLM в 2026 году — это не игрушки для энтузиастов. Это рабочие инструменты, которые решают конкретные бизнес-задачи. Переводчик Docker-команд — лишь один пример из сотен возможных. Следующий на очереди — переводчик ошибок из логов. Но это уже другая история.