Перейти к содержимому
ПереводыQwen, InternLM и другие

InternLM Camp: пересказ ключевых туториалов L0–L2

Своими словами — главные практические занятия четвёртого сезона InternLM Camp: задание на отладку из L0, «самосознание» модели в XTuner, RAG на LlamaIndex, оценка в OpenCompass и арифметика видеопамяти при квантовании в LMDeploy — с командами и переносом на вашу машину.

На острове входа есть задание, которое стоит сделать и вам — оно учит главному навыку работы с LLM в коде.

Дан короткий скрипт: он отправляет в API InternLM абзац о модели и просит вернуть JSON с четырьмя полями (название модели, организация, размеры, длина контекста), а потом делает json.loads(ответ). Скрипт падает с ошибкой. Задача — поставить точку останова в отладчике VSCode, посмотреть, что на самом деле вернула модель, и найти причину. Подсказка авторов: ошибка «связана с выводом LLM».

Скорее всего (это наше объяснение, ответ в оригинале не приводится), модель оборачивает JSON в блок разметки (три обратных апострофа и слово json) или добавляет вежливую фразу до и после. Строка перестаёт быть чистым JSON — и json.loads падает. Чинить можно тремя способами, от слабого к сильному: вырезать JSON регулярным выражением; попросить в промпте «только JSON без пояснений»; использовать структурированный вывод API (урок 8.1.2).

Ещё один урок из этого задания авторы подчёркивают отдельно: в учебном скрипте ключ API записан прямо в коде, и это крайне плохая практика — храните ключи в переменных окружения.

Задача — дообучить InternLM2.5-7B-Chat так, чтобы на «кто ты?» модель отвечала, что она — помощник конкретного человека (в туториале — по имени автора). Это тот же жанр, что «самосознание» в ms-swift из документации Qwen: маленькая заметная цель, на которой видно, что дообучение сработало.

Туториал написан под «30% A100» (24 ГБ) и QLoRA. Порядок:

  1. Окружение. conda-окружение с Python 3.10, установка XTuner по замороженному requirements.txt из репозитория. Проверка: xtuner list-cfg выводит список готовых конфигураций (их названия читаются как «модель_метод_датасет_эпохи», например internlm2_5_chat_7b_qlora_alpaca_e3).
  2. Данные. В репозитории лежит готовый assistant_Tuner.jsonl — диалоги, где модель рассказывает о себе. Небольшой скрипт на Python проходит по всем строкам JSONL и заменяет в них имя на ваше. Проверяете результат head -n 3.
  3. Конфигурация. xtuner copy-cfg internlm2_5_chat_7b_qlora_alpaca_e3 ./config — скопировать готовую конфигурацию и поправить несколько строк: путь к модели, путь к своему JSONL вместо датасета Alpaca, загрузку из локального JSON вместо Hugging Face, отключить функцию преобразования Alpaca (данные уже в нужном формате) и заменить контрольные вопросы на «представься, пожалуйста». В туториале — таблица основных параметров: max_length, pack_to_max_length (склейка коротких примеров), accumulative_counts (накопление градиента), lr, max_epochs, warmup_ratio, max_norm (обрезка градиента) и др.
  4. Обучение. xtuner train <config> --deepspeed deepspeed_zero2 --work-dir ./work_dirs/assistTuner.
  5. Конвертация. XTuner сохраняет чекпойнт PyTorch (.pth); xtuner convert pth_to_hf <config> <pth> ./hf превращает его в формат Hugging Face. Для LoRA это и есть «адаптер»: adapter_config.json + adapter_model.bin.
  6. Слияние. xtuner convert merge <исходная модель> ./hf ./merged --max-shard-size 2GB — вливает адаптер в веса, получается обычная модель. Авторы поясняют: при полном дообучении этот шаг не нужен — там меняются сами веса, а не обучается отдельный адаптер.
  7. Проверка в веб-демо на Streamlit: модель представляется по-новому.

Предупреждение из туториала, полезное и вам: если увеличивать batch_size для лучшей загрузки GPU, качество чат-модели может пострадать — следите за ответами, а не только за скоростью.

На вашей машине. QLoRA 7B помещается на одну RTX 4080; на четырёх картах — NPROC_PER_NODE=4 xtuner train …. Тот же опыт на Qwen3 — в уроке 6.2.2 через LLaMA-Factory.

Идея занятия очень наглядна. Берут маленькую InternLM2-Chat-1.8B и спрашивают: «что такое xtuner?» Модель не знает — XTuner появился после её обучения, — и отвечает невпопад. Затем в базу знаний кладут README самого XTuner и задают тот же вопрос через RAG — ответ становится правильным. До/после на одном вопросе.

Шаги (локальная версия):

  1. Установить llama-index и пакеты интеграций llama-index-llms-huggingface, llama-index-embeddings-huggingface (в туториале версии закреплены — llama-index 0.10.38).
  2. Скачать модель эмбеддингов sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 (многоязычная, лёгкая). Авторы отмечают, что можно взять и другую открытую модель эмбеддингов.
  3. Скачать ресурсы NLTK: обычно они качаются сами, но из-за сети это может не получиться, и туториал берёт их с зеркала на Gitee.
  4. Проверить модель без RAG: HuggingFaceLLM(...) и вопрос «Что такое xtuner?» (в туториале — по-китайски) — ответ плохой.
  5. Склонировать репозиторий XTuner, положить его README_zh-CN.md в папку данных, построить VectorStoreIndex из SimpleDirectoryReader, задав эмбеддер и LLM через Settings, — и спросить снова.
  6. Обернуть всё в веб-интерфейс на Streamlit; продвинутое задание — выложить его как Space на Hugging Face.

Обязательное задание уровня — найти свой вопрос, на который модель без RAG не отвечает, а с RAG отвечает, и показать оба скриншота. Сделайте так же на русском: возьмите документ о событии после даты обучения модели. Подробнее о шагах RAG — наш перевод урока 2.2 курса Alibaba ACP и урок 8.2.1.

Три сценария оценки — именно в таком порядке их полезно освоить.

  1. Модель за API. Описать модель конфигурацией с классом OpenAISDK (адрес API, ключ, имя модели), описать маленький датасет — в туториале это демо-версия CMMLU, где из каждого датасета берутся только первые 2 примера, и прогон занимает около 10 минут, — и запустить python run.py --models <модель> --datasets <датасет> --debug.
  2. Локальная модель. Подготовить архив датасетов OpenCompass, поправить готовую конфигурацию hf_internlm2_5_1_8b_chat.py (класс HuggingFacewithChatTemplate, путь к весам) и запустить оценку на C-Eval: python run.py --datasets ceval_gen --models hf_internlm2_5_1_8b_chat --debug. Флаг --debug совет авторов для первого запуска: OpenCompass по умолчанию запускает задачи параллельно, и ошибки теряются.
  3. Локальная модель за своим API. Поднять модель сервером LMDeploy (lmdeploy serve api_server <путь> --server-port 23333) и оценивать её как API-модель (opencompass --models <конфигурация с классом OpenAI> --datasets ceval_gen). Так проверяют, не испортило ли качество развёртывание (например, квантование).

Продвинутые задания — субъективная оценка (модель-судья) и оценка модели после развёртывания в LMDeploy. Связь с курсом — урок 7.3.1 о бенчмарках и их ловушках и 7.3.2 о модели-судье.

L2, уровень 3: квантование в LMDeploy и арифметика видеопамяти

Заголовок раздела «L2, уровень 3: квантование в LMDeploy и арифметика видеопамяти»

Лучшая часть туториала — подсчёт, куда уходит видеопамять, для InternLM2.5-7B на карте с 24 ГБ. Разберём его логику (числа — из оригинала).

Видеопамять делится на три части: веса, KV-кэшKV-кэшEN KV cache и «прочее» (промежуточные вычисления, служебные буферы). LMDeploy отдаёт под KV-кэш долю оставшейся после весов памяти — параметр --cache-max-entry-count, по умолчанию 0,8.

КонфигурацияВесаKV-кэшПрочееИтого
bf16, по умолчанию14 ГБ(24−14)×0,8=8(24-14)\times 0{,}8 = 8 ГБ1 ГБ23 ГБ
bf16, --cache-max-entry-count 0.414 ГБ10×0,4=410 \times 0{,}4 = 4 ГБ1 ГБ19 ГБ
W4A16 (AWQ), по умолчанию3,5 ГБ(24−3,5)×0,8=16,4(24-3{,}5)\times 0{,}8 = 16{,}4 ГБ1 ГБ20,9 ГБ
W4A16 + 0.4 + KV-кэш в int43,5 ГБ20,5×0,4=8,220{,}5 \times 0{,}4 = 8{,}2 ГБ1,8 ГБ13,5 ГБ

Как это читать:

  • 14 ГБ весов: 7 млрд параметров × 2 байта (bf16). После 4-битного квантования весов — в 4 раза меньше, 3,5 ГБ.
  • Квантование весов почти не уменьшило итог (23 → 20,9 ГБ), потому что освобождённое место LMDeploy тут же отдал под KV-кэш. Зато в кэш теперь влезает вдвое больше токенов — больше одновременных запросов.
  • --quant-policy 4 хранит KV-кэш в int4 (8 — в int8): квантование «по головам и по токенам», несимметричное. При тех же гигабайтах кэша в int4 помещается в 4 раза больше значений, чем в bf16.
  • W4A16 значит: веса (W, weights) — 4-битные целые, активации (A) — 16-битные числа с плавающей точкой.

Команды:

Окно терминала
# чат в терминале с ограничением KV-кэша
lmdeploy chat /path/to/internlm2_5-7b-chat --cache-max-entry-count 0.4
# квантовать веса в 4 бита алгоритмом AWQ (калибровка на ptb: 128 примеров по 2048 токенов, группы по 128)
lmdeploy lite auto_awq /path/to/internlm2_5-7b-chat \
--calib-dataset 'ptb' --calib-samples 128 --calib-seqlen 2048 \
--w-bits 4 --w-group-size 128 --batch-size 1 \
--work-dir /path/to/internlm2_5-7b-chat-w4a16-4bit
# OpenAI-совместимый сервер: AWQ-модель + KV-кэш в int4 + 40% свободной памяти под кэш
lmdeploy serve api_server /path/to/internlm2_5-7b-chat-w4a16-4bit \
--model-format awq --quant-policy 4 --cache-max-entry-count 0.4 --server-port 23333

Авторы предупреждают, что квантование 7B-модели на их облачной машине заняло бы около 8 часов, и предлагают потренироваться на 1.8B. На RTX 4080 это заметно быстрее, но тоже не минуты — делайте на маленькой модели. Дальше в туториале — то же для мультимодальной InternVL2 и вызов функций через API LMDeploy (задание: заставить модель вызвать функции «сложить» и «умножить»).

Перенос на курс. Сравните таблицу с подсчётом для vLLM в уроке 7.1.2: там тот же принцип (--gpu-memory-utilization — доля всей памяти, а не оставшейся). Что такое AWQ и почему квантуют группами — урок 7.2.1; откуда берётся размер KV-кэша — урок 4.6.4.

Туториал начинается с понятия агента и двух подходов к вызову инструментов: универсальные схемы (ReAct и подобные — модель следует формату по инструкции) и специально обученные модели (формат вызова встроен обучением). Затем — Lagent, лёгкий фреймворк агентов лаборатории: использование готового агента, свой агент со своим инструментом и мультиагентная система для написания блога (агент-автор пишет структурированную статью по теме, агент-критик разбирает её, указывает слабые места и подбирает литературу). Финал — развёртывание на Hugging Face Spaces со Streamlit. Сравните с устройством Qwen-Agent в нашем путеводителе.

EnglishРусский
fine-tuningдообучение
self-cognition«самосознание» (ответы о себе)
weight conversion / mergingконвертация весов / слияние
evaluationоценка
quantized deploymentразвёртывание с квантованием
GPU memory usageрасход видеопамяти
online KV-cache quantizationквантование KV-кэша на лету
breakpoint debuggingотладка с точками останова