Автоматизация fine-tuning и квантования моделей: Codex + HF-skills | AiManual
AiManual Logo Ai / Manual.
18 Янв 2026 Гайд

Как автоматизировать тонкую настройку и квантование моделей с помощью Codex и HF-skills: полный туториал

Полный гайд по автоматизации ML-пайплайна: от fine-tuning до GGUF-квантования через агентов. Код, команды, мониторинг Trackio.

Почему автоматизация ML-пайплайна до сих пор похожа на цирк с конями?

Ты запускаешь fine-tuning. Ждешь 8 часов. Проверяешь логи. Находишь ошибку в предобработке данных. Исправляешь. Запускаешь снова. Еще 8 часов. Потом квантование. Потом тесты. Потом выгрузка. За неделю ты тратишь 60 часов на рутину и 2 часа на реальную работу.

Знакомо? Я тоже через это проходил.

Пока корпорации строят сложные MLOps-платформы за миллионы, есть простой способ автоматизировать весь цикл: от загрузки датасета до публикации GGUF-модели. Без единой строчки кода вручную. Без мониторинга логов в полночь. Без нервного тика при виде "CUDA out of memory".

Сегодня соберем систему, где агенты делают за тебя всю грязную работу.

Важно: эта система не для разовых экспериментов. Если ты тренируешь модель раз в месяц, ручные методы проще. Но если у тебя пайплайн из 5+ шагов, который повторяется регулярно — читай дальше.

Архитектура: что склеивает агентов в работающую систему

Забудь про "возьми этот скрипт и запусти". Наша цель — полностью автономный пайплайн:

  1. Агент-оркестратор (Claude Code) получает задачу: "Дообучи Gemma 2B на медицинских данных"
  2. Он разбивает задачу на подзадачи: подготовка данных → fine-tuning → оценка → квантование → публикация
  3. Каждую подзадачу выполняет специализированный агент через HF-skills
  4. Trackio собирает метрики и логи, отправляет уведомления
  5. В конце система выдает GGUF-файл и ссылку на Hugging Face Hub

Звучит как фантастика? Это уже работает. И дешевле, чем нанимать джуна, который будет сидеть над ноутбуком сутками.

1 Подготовка: собираем инструменты

Тебе понадобится:

  • Аккаунт на Hugging Face с доступом к Inference Endpoints (или свой сервер с GPU)
  • Claude Code API ключ (или локальная LLM для кодинга — например, из этого обзора)
  • Python 3.10+ с установленными библиотеками
  • Базовое понимание, как работает fine-tuning (если нет — сначала прочитай этот гайд по медицинской настройке)
# Устанавливаем базовые зависимости
pip install huggingface-hub transformers datasets peft trl accelerate
pip install anthropic  # для Claude Code API
pip install gguf  # для работы с квантованными моделями
💡
Не пытайся установить всё сразу на слабую машину. HF-skills могут работать удаленно через Inference Endpoints. Твоя локальная машина нужна только для оркестрации.

2 Настраиваем HF-skills: даём агентам руки

HF-skills — это набор инструментов, которые позволяют агентам работать с экосистемой Hugging Face. Вместо того чтобы писать сложные скрипты, ты описываешь задачу на естественном языке.

Вот как выглядит типичный сценарий:

from hf_skills import FineTuner, Quantizer, Evaluator
from claude_code import ClaudeCoder

# Инициализируем агента-оркестратора
agent = ClaudeCoder(api_key="your_key_here")

# Описываем задачу
task = """
Fine-tune модель google/gemma-2b-it на датасете medical_qa.
Использовать LoRA с rank=16.
Обучить 3 эпохи с learning_rate=2e-4.
После обучения сделать квантование в GGUF формат с q4_k_m.
Загрузить результат на Hugging Face Hub.
"""

# Агент сам разбивает задачу и вызывает нужные skills
result = agent.execute_with_skills(task)

В теории всё просто. На практике агенты тупят на мелочах. Вот самые частые косяки:

Ошибка 1: Агент не понимает контекст задачи. Если сказать "сделай квантование", он может выбрать неоптимальные параметры. Всегда явно указывай: "использовать imatrix для лучшего качества" (про imatrix подробнее в отдельном гайде).

Ошибка 2: Агент забывает про ограничения памяти. 40B-модель на карте 24GB? Привет, OOM. Всегда указывай доступные ресурсы явно: "у меня 48GB VRAM" (кстати, про модифицированные 48GB RTX 4090 есть интересная статья).

3 Пишем оркестратор: мозг системы

Claude Code — не волшебная таблетка. Ему нужна четкая инструкция. Вот шаблон, который реально работает:

import json
from datetime import datetime

class MLPipelineOrchestrator:
    def __init__(self, hf_token, claude_api_key):
        self.hf_token = hf_token
        self.agent = ClaudeCoder(api_key=claude_api_key)
        
    def run_pipeline(self, config):
        """
        config = {
            'base_model': 'google/gemma-2b-it',
            'dataset': 'medical_qa',
            'task_type': 'instruction_following',
            'lora_rank': 16,
            'epochs': 3,
            'quantization': 'q4_k_m',
            'use_imatrix': True,  # Важно для качественного квантования
            'output_hf_repo': 'your-username/medical-gemma-2b-gguf'
        }
        """
        
        steps = [
            self._prepare_data,
            self._fine_tune,
            self._evaluate,
            self._quantize,
            self._upload_to_hub
        ]
        
        results = {}
        for step in steps:
            step_name = step.__name__.replace('_', ' ').title()
            print(f"[ {datetime.now().strftime('%H:%M:%S')} ] Starting: {step_name}")
            
            try:
                result = step(config)
                results[step.__name__] = result
                print(f"[ {datetime.now().strftime('%H:%M:%S')} ] Completed: {step_name}")
            except Exception as e:
                print(f"[ {datetime.now().strftime('%H:%M:%S')} ] Failed: {step_name} - {str(e)}")
                # Здесь можно добавить логику повтора или уведомление
                raise
        
        return results
    
    def _fine_tune(self, config):
        # Агент генерирует код для fine-tuning на лету
        prompt = f"""
        Write a complete fine-tuning script for:
        Model: {config['base_model']}
        Dataset: {config['dataset']}
        Use LoRA with rank={config['lora_rank']}
        Training epochs: {config['epochs']}
        Task type: {config['task_type']}
        
        Requirements:
        1. Use PEFT library
        2. Save checkpoints every epoch
        3. Log metrics to WandB
        4. Handle OOM errors gracefully
        """
        
        code = self.agent.generate_code(prompt)
        
        # Сохраняем и выполняем сгенерированный код
        with open('finetune_script.py', 'w') as f:
            f.write(code)
        
        # Запускаем через subprocess с мониторингом
        # ...

Ключевой момент: каждый шаг должен быть идемпотентным. Если квантование упало на 90%, ты должен иметь возможность перезапустить только его, а не весь пайплайн с начала.

4 Квантование в GGUF: где агенты спотыкаются чаще всего

Квантование — самый капризный этап. Особенно если нужна imatrix. Вот как заставить агента сделать это правильно:

def _quantize(self, config):
    """
    Генерация скрипта для квантования с imatrix
    """
    
    prompt = f"""
    Write a script to convert and quantize a Hugging Face model to GGUF format.
    
    Input model: ./fine-tuned-model (directory with Hugging Face format)
    Output: ./quantized-model.gguf
    
    Requirements:
    1. Use llama.cpp for conversion
    2. Quantization type: {config['quantization']}
    3. Generate imatrix first using calibration data
    4. Calibration data: 100 samples from {config['dataset']}
    5. Apply quantization with the generated imatrix
    6. Verify the output GGUF file is valid
    
    Important: Handle large models that don't fit in memory by using
    memory-efficient conversion methods.
    """
    
    code = self.agent.generate_code(prompt)
    
    # Проверяем, что агент не наделал глупостей
    required_imports = ['llama_cpp', 'json', 'numpy']
    for imp in required_imports:
        if imp not in code:
            print(f"Warning: missing {imp} import, adding manually")
            code = f"import {imp}\n" + code
    
    # Если нужно работать с большими моделями
    if '40b' in config['base_model'].lower() or '70b' in config['base_model'].lower():
        if '--split-max-tensors' not in code:
            print("Adding tensor splitting for large model")
            code = code.replace('llama.cpp', 'llama.cpp --split-max-tensors')
    
    return self._execute_quantization(code, config)

Почему так сложно? Потому что агенты не понимают разницу между "теоретически возможным" и "практически работающим". Они могут сгенерировать код, который компилируется, но падает на реальных данных. Всегда добавляй проверки.

💡
Для особо сложных случаев квантования используй готовые UI-инструменты вроде GGUF Converter Studio или GGUF Tool Suite Web UI. Агент может подготовить данные, а конвертацию сделать через интерфейс.

5 Мониторинг и логирование: Trackio вместо бессонных ночей

Запустил пайплайн и ушел пить кофе? Вернёшься к разбитому корыту. Или к успешно завершённой задаче. Разница — в мониторинге.

Trackio (или любой подобный инструмент) должен отслеживать:

  • Использование GPU памяти (рост = утечка)
  • Loss кривую (если не падает — что-то не так)
  • Прогресс квантования (проценты, а не "работаю")
  • Ошибки (сразу в телеграм, а не в лог-файле)
import trackio

tracker = trackio.Tracker(
    project_name="medical-finetuning",
    api_key="your_trackio_key",
    alerts_enabled=True,
    alert_channels=["telegram", "email"]
)

def monitored_step(step_func, step_name, config):
    """Обёртка для отслеживания шагов"""
    with tracker.span(step_name):
        # Логируем начало
        tracker.log(f"Starting {step_name} with config: {json.dumps(config, indent=2)}")
        
        try:
            result = step_func(config)
            tracker.log(f"{step_name} completed successfully")
            tracker.metric(f"{step_name}_success", 1)
            return result
        except Exception as e:
            tracker.error(f"{step_name} failed: {str(e)}")
            tracker.metric(f"{step_name}_failure", 1)
            # Автоматически создаём тикет в issue tracker
            tracker.create_issue(
                title=f"Pipeline failed at {step_name}",
                description=str(e),
                priority="high"
            )
            raise

Теперь если fine-tuning упадет на 3-й эпохе из-за NaN в градиентах, ты получишь сообщение в телеграм с полным контекстом. Не через 8 часов, а сразу.

6 Публикация на Hugging Face Hub: финальный аккорд

Агенты любят загружать модели с кривыми метаданными. Потом месяц ищешь в Hub свою модель, потому что она называется "model-gguf" без тегов.

def _upload_to_hub(self, config):
    """Умная загрузка с правильными метаданными"""
    
    prompt = f"""
    Write a script to upload a GGUF model to Hugging Face Hub.
    
    Model file: ./quantized-model.gguf
    Target repo: {config['output_hf_repo']}
    HF token: [HF_TOKEN]
    
    Requirements:
    1. Create README.md with:
       - Model description
       - Training details
       - Quantization info
       - Usage example
       - License (Apache 2.0)
    2. Add tags: ['gguf', 'quantized', 'medical', 'gemma']
    3. Upload model file
    4. Set model card metadata properly
    5. Make repo private initially, then public after verification
    """
    
    code = self.agent.generate_code(prompt)
    
    # Заменяем placeholder на реальный токен
    code = code.replace('[HF_TOKEN]', f'"{self.hf_token}"')
    
    # Добавляем проверку размера файла
    if 'os.path.getsize' not in code:
        code = code.replace(
            '# Upload model file',
            '# Check file size\nimport os\nfile_size = os.path.getsize(\"./quantized-model.gguf\")\nprint(f\"Uploading {file_size / 1024**3:.2f} GB\")\n\n# Upload model file'
        )
    
    return self._execute_upload(code)

Где система ломается (и как чинить)

Проблема Причина Решение
Агент генерирует код, который не работает Недостаточный контекст в промпте Добавляй примеры кода в промпт. Покажи, как ты делал бы это вручную.
Fine-tuning падает на OOM Агент не учитывает доступную память Явно указывай: "available VRAM: 24GB, use gradient checkpointing, batch size max 2"
Квантование занимает вечность Агент не использует imatrix или выбирает медленный метод Специфицируй: "use q4_k_m with imatrix, prioritize speed over smallest size"
Модель на Hub без метаданных Агент загружает только файл Давай шаблон README.md и требуй заполнить все поля

Сколько это стоит на самом деле?

Давай посчитаем на примере Gemma 2B:

  • Claude Code API: $0.02 за 1K токенов генерации кода. На весь пайплайн ~50K токенов = $1
  • Hugging Face Inference Endpoints: A10G (24GB) = $1.05/час. Fine-tuning 3 эпохи = 4 часа = $4.20
  • Квантование на CPU (c6i.2xlarge): $0.34/час, 2 часа = $0.68
  • Итого: ~$6 за одну итерацию

Твое время на ручное выполнение: минимум 2 часа активной работы (плюс 8 часов ожидания). При ставке $50/час = $100.

Экономия 94%. И ты не тратишь нервы.

Важный нюанс: первые 2-3 итерации ты потратишь на отладку системы. Не жди, что с первого раза всё заработает идеально. Но после настройки она будет воспроизводимо работать десятки раз.

Что дальше? Куда двигаться после базовой автоматизации

Когда система работает стабильно:

  1. Добавь A/B тестирование моделей — пусть агент тренирует 3 варианта с разными гиперпараметрами и выбирает лучший по метрикам
  2. Интегрируй RLHF — если нужно выравнивание по человеческим предпочтениям (про RLHF есть отличный пример в этой статье про автоматизацию обучения)
  3. Настрой каскадное квантование — создавай сразу несколько версий (q4_k_m, q5_k_m, q8_0) для разных use case
  4. Добавь автоматическое тестирование — после загрузки на Hub запускай инференс-тесты, проверяй, что модель действительно работает

Самая большая ошибка — пытаться автоматизировать всё и сразу. Начни с одного шага (например, fine-tuning), добейся стабильной работы, потом добавь квантование, потом мониторинг.

Через месяц у тебя будет система, которая делает за тебя 80% рутинной ML-работы. Ты останешься с интересными задачами: проектирование архитектур, анализ результатов, постановка экспериментов.

А не с дебагом CUDA ошибок в 3 часа ночи.