English translation is not available yet. Showing Russian content.

Настройка AWQ квантизации для LLM

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настройка AWQ квантизации для LLM

1. Цель задачи

Научиться применять метод AWQ (Activation-aware Weight Quantization) для 4-битного сжатия LLM совместимым с инференсом способом. Выполнить квантизацию модели на основе калибровочного датасета, измерить качество (perplexity, accuracy) против FP16-базлайна и оценить выигрыш по памяти и скорости инференса.

Ключевой результат Квантизированная модель с качеством не ниже 99% от FP16 при снижении потребления VRAM на 75% и корректно работающий инференс.


2. Исходные данные

Что нужноОткуда взять
LLM для квантизации (например, HuggingFaceH4/zephyr-7b-beta или mistralai/Mistral-7B-v0.1)Hugging Face Hub (требуется токен)
Калибровочный датасет для AWQ (например, случайные выборки из c4 или wikitext)Hugging Face datasets, скачать 128-256 примеров
Датасет для оценки качества (perplexity)wikitext-2 (test split)
Датасет для оценки accuracy (классификация/генерация)openbookqa, hellaswag или truthfulqa (по выбору)
GPU с CUDA (минимум 8 GB VRAM)Локальный/облачный сервер; при отсутствии — симулировать на CPU с моделью 1B
Python 3.10+, установленные библиотекиСм. раздел 3

Если нет реального GPU — симулируем:

  1. Скачайте модель TinyLlama/TinyLlama-1.1B-Chat-v1.0 (подойдёт 1 GB VRAM на CPU).
  2. Квантизация будет медленной, но процесс тот же.
  3. Для замера памяти используйте psutil вместо nvidia-smi.
  4. Для оценки качества ограничьтесь измерением perplexity на 100 примерах.

3. Технологический стек

КомпонентИнструментыНазначение
Управление версиями Pythonconda / venv + pipИзолированное окружение
Базовые библиотекиtorch, transformers, datasets, accelerateЗагрузка модели, датасетов, батч-процессинг
Квантизацияauto-gptq (>=0.7.0) + awqПрименение AWQ алгоритма
Замер качестваevaluate, lm-eval-harnessPerplexity, accuracy
Профилированиеnvidia-ml-py, torch.cuda.memory_summary()Память и время инференса
Мониторингnvitop / nvidia-smiVRAM в реальном времени
Логированиеwandb (опционально)Сравнение экспериментов

4. Этапы выполнения

Этап 1: Подготовка окружения и загрузка baseline (30 минут)

Действия

  1. Создать conda-окружение с Python 3.10:

    conda create -n awq python=3.10
    conda activate awq
    
  2. Установить зависимости:

    pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
    pip install transformers datasets accelerate evaluate
    pip install auto-gptq
    # Для профилирования
    pip install nvidia-ml-py psutil
    
  3. Загрузить FP16 baseline модель и токенизатор:

    from transformers import AutoModelForCausalLM, AutoTokenizer
    model_name = "HuggingFaceH4/zephyr-7b-beta"  # или выбранная модель
    tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
    model_fp16 = AutoModelForCausalLM.from_pretrained(
        model_name, torch_dtype=torch.float16, device_map="auto", trust_remote_code=True
    )
    model_fp16.eval()
    
  4. Загрузить датасеты (калибровочный и для оценки):

    from datasets import load_dataset
    calib_dataset = load_dataset("c4", "en", split="train", streaming=True).take(256)
    eval_dataset = load_dataset("wikitext", "wikitext-2-raw-v1", split="test")
    

Ожидаемый результат этапа Рабочее окружение, загруженные FP16 модель, токенизатор, датасеты.


Этап 2: AWQ квантизация (1 час)

Действия

  1. Подготовить калибровочные данные — токенизировать примеры из calib_dataset, обрезать до 2048 токенов:

    def tokenize_calib(examples):
        return tokenizer(examples["text"], truncation=True, max_length=2048)
    calib_tokens = calib_dataset.map(tokenize_calib, batched=True)
    calib_tokens = calib_tokens["input_ids"]
    
  2. Загрузить квантизатор из auto_gptq с конфигурацией AWQ:

    from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
    quantize_config = BaseQuantizeConfig(
        bits=4,
        group_size=128,           # стандартный размер группы для AWQ
        damp_percent=0.01,
        desc_act=True,
        quant_method="awq"        # используем AWQ
    )
    
  3. Выполнить квантизацию:

    model_awq = AutoGPTQForCausalLM.from_pretrained(
        model_name,
        quantize_config,
        device="cuda:0"
    )
    model_awq.quantize(calib_tokens, use_triton=False)  # use_triton=True если поддерживается
    model_awq.save_quantized("./zephyr-7b-awq-4bit")
    
  4. Перезагрузить квантизированную модель и проверить её работу:

    model_quant = AutoGPTQForCausalLM.from_quantized(
        "./zephyr-7b-awq-4bit",
        device="cuda:0"
    )
    

Ожидаемый результат этапа Сохранённая AWQ-модель, способная генерировать текст.


Этап 3: Оценка качества (1 час)

Действия

  1. Perplexity на WikiText-2 Реализовать вычисление:

    def compute_perplexity(model, encodings):
        import torch.nn.functional as F
        with torch.no_grad():
            logits = model(encodings.input_ids.to("cuda"), labels=encodings.input_ids.to("cuda"))
            loss = logits.loss
        return torch.exp(loss).item()
    
    • Использовать первые 1000 строк тестовой выборки.
    • Замерить perplexity для FP16 baseline и для AWQ.
  2. Accuracy (опционально) — на задаче hellaswag с помощью lm_eval:

    pip install lm_eval==0.4.2
    lm_eval --model hf --model_args pretrained=./zephyr-7b-awq-4bit --tasks hellaswag --num_fewshot 0
    

    Или вручную: взять 100 примеров, сгенерировать завершения, сравнить с ответами.

  3. Сравнить метрики

    • Perplexity: ppl_fp16 vs ppl_awq.
    • Accuracy: acc_fp16 vs acc_awq.
    • Относительная деградация: (ppl_awq / ppl_fp16 - 1) * 100%.

Ожидаемый результат этапа Таблица метрик (см. пример ниже) и вывод о том, достигнуто ли качество 99% (т.е. относительная деградация ≤1%).


Этап 4: Замер производительности и памяти (30 минут)

Действия

  1. Пиковое потребление VRAM (при инференсе одного промпта длиной 512 токенов):

    torch.cuda.reset_peak_memory_stats()
    _ = model_fp16.generate(inputs, max_new_tokens=128)
    peak_fp16 = torch.cuda.max_memory_allocated() / (1024**3)
    
    torch.cuda.reset_peak_memory_stats()
    _ = model_quant.generate(inputs, max_new_tokens=128)
    peak_awq = torch.cuda.max_memory_allocated() / (1024**3)
    
  2. Latency — усреднить время генерации 128 токенов для 10 запусков:

    import time
    start = time.time()
    for _ in range(10):
        model.generate(inputs, max_new_tokens=128)
    avg = (time.time() - start) / 10
    
  3. Заполнить итоговую таблицу

МодельVRAM (GB)Latency (sec)PerplexityAccuracy
FP16XYZW
AWQ 4bitX'Y'Z'W'

Ожидаемый результат этапа Замеры, подтверждающие снижение памяти ~75% (сравнить: (X-X')/X ≈ 0.75).


Этап 5: Анализ и отчёт (30 минут)

Действия

  1. Записать выводы:
    • Выполнено ли условие "Quality 99%" (относительная деградация perplexity ≤1%).
    • Выполнено ли условие "Memory -75%" (снижение ≥75%).
  2. Сформулировать, при каких условиях AWQ даёт лучший/худший результат.
  3. Оформить отчёт в Markdown (например, README.md).

Ожидаемый результат этапа Файл report.md с таблицей и анализом.


5. Критерии приемки (Definition of Done)

  • FP16 baseline модель загружается и работает без ошибок.
  • AWQ квантизация выполнена с помощью auto_gptq, модель сохранена.
  • Perplexity на Wikitext-2 для AWQ отличается от FP16 не более чем на 1% (относительно).
  • Пиковое потребление VRAM при инференсе снижено минимум на 75% (сравнение FP16 vs AWQ).
  • Модель способна генерировать осмысленный текст (на одном примере).
  • Подготовлен отчёт в формате Markdown, содержащий:
    • использованные гиперпараметры квантизации;
    • таблицу сравнения метрик;
    • график распределения оценок (опционально);
    • выводы.

6. Ожидаемый результат

Основной артефакт Папка zephyr-7b-awq-4bit (или аналогичная) с квантизированной моделью, пригодной для загрузки через AutoGPTQForCausalLM.from_quantized.

Дополнительно

  • Скрипт quantize_and_eval.py (воспроизводимый пайплайн).
  • Отчёт report.md с метриками и выводами.
  • (Опционально) Экспорт в W&B или локальный CSV.

7. Возможные сложности и их решение

СложностьРешение
Не хватает VRAM для квантизации (даже для FP16)Использовать модель меньшего размера (1-3B) или CPU-режим с device_map="cpu".
Ошибка CUDA out of memory при квантизацииУменьшить batch_size в конфиге квантизации (параметр calib_batch_size=1).
auto_gptq не устанавливается или устарелОбновить pip install --upgrade auto-gptq, установить torch совместимой версии.
Деградация качества >1%Попробовать другие значения group_size (64 или 32) или увеличить damp_percent.
Нет доступа к Hugging FaceИспользовать модели из локального кэша или S3.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Подготовка окружения30 мин
Этап 2: AWQ квантизация1 ч
Этап 3: Оценка качества1 ч
Этап 4: Замер производительности30 мин
Этап 5: Анализ и отчёт30 мин
Итого3 ч 30 мин

Примечание Для первого раза заложите дополнительно 1–2 ч на отладку зависимостей и исправление ошибок.


9. Связанные вопросы из базы знаний

ВопросТема
42Основы квантизации нейросетей
87PTQ vs QAT: методы посттренировочной квантизации
1344-битные форматы: NF4, GPTQ, AWQ
209Настройка AWQ (текущая задача)
301Perplexity как метрика качества LLM
405Оптимизация инференса через квантизацию
512Сравнение скорости GPU vs CPU при инференсе
623Calibration dataset для квантизации
744Профилирование памяти PyTorch моделей
808Интеграция квантизированных моделей в production

10. Чек-лист самопроверки

  • Я установил все зависимости и проверил, что модель FP16 загружается.
  • Я выполнил AWQ квантизацию и сохранил результат.
  • Я замерил perplexity для обеих моделей и подтвердил, что разница ≤1%.
  • Я замерил VRAM и убедился, что снижение составило ≥75%.
  • Я оформил отчёт с таблицей и выводами, готовый к демонстрации.