PEFT documentation
Картриджи
Картриджи
Cartridges — это метод обучения по промптам, который хранит сжатое представление длинного контекста в виде параметризованного префикса KV-кэша. Основная идея взята из статьи Cartridges: Lightweight and general-purpose long context representations via self-study.
Для высокоуровневого обзора и мотивации см. блог-пост Cartridges: Storing long contexts in tiny caches with self-study.
Чем Cartridges отличаются от Prefix Tuning
Оба метода, Prefix Tuning и Cartridges, работают за счёт внедрения past_key_values (префиксного KV-кэша) в базовую модель.
- Prefix Tuning обучает эмбеддинги виртуальных токенов (и, при необходимости, проекцию MLP) и формирует KV-префикс.
- Cartridges напрямую обучают сам KV-префикс (векторы ключей/значений для каждого слоя для
pвиртуальных токенов) и предназначены для инициализации из реального KV-префикса prefill (например, из первыхpтокенов корпуса/системного промпта).
В статье также рекомендуется замораживать первый токен в качестве attention sink для обеспечения стабильности (по умолчанию num_frozen_tokens=1).
Использование (инференс)
Загрузите обученный адаптер CARTRIDGE и запустите генерацию:
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
model_id = "Qwen/Qwen2.5-0.5B-Instruct"
adapter_path = "path/to/cartridge_adapter"
base = AutoModelForCausalLM.from_pretrained(model_id)
model = PeftModel.from_pretrained(base, adapter_path)
tok = AutoTokenizer.from_pretrained(model_id)
if tok.pad_token is None:
tok.pad_token = tok.eos_token
out = model.generate(**tok("Question about the corpus:", return_tensors="pt"), max_new_tokens=64)
print(tok.decode(out[0], skip_special_tokens=True))Если вам нужно создать и инициализировать картридж перед обучением, см. варианты инициализации ниже.
Варианты инициализации
В статье обсуждается несколько практических стратегий инициализации:
- Случайный KV (по умолчанию): создайте
CartridgeConfigи начните обучение. Это инициализирует KV-префикс случайным образом. - KV из первых токенов промпта/корпуса: используйте
initialize_kv_prefix_from_text(model, tokenizer, text=...). Это выполняет prefill дляtextи копирует полученный KV-кэш для первыхnum_virtual_tokensв адаптер. - KV из существующего кэша: используйте
initialize_kv_prefix_from_past_key_values(model, past_key_values=...), если у вас уже есть объектpast_key_valuesиз префилла базовой модели.
Обучение
Статья Cartridges предлагает цель дистилляции SELF-STUDY (замороженная базовая модель предоставляет teacher logits; адаптер CARTRIDGE обучается так, чтобы модель-студент совпадала с распределением следующего токена модели-учителя на целевом сегменте).
PEFT выносит логику обучения за пределы основной библиотеки; см. https://github.com/huggingface/peft/tree/main/examples/cartridge_self_study для эталонного рабочего процесса.
Скрипты примеров используют замороженную базовую модель в качестве учителя и адаптированную модель в качестве студента, поэтому обе разделяют один и тот же базовый checkpoint.
Состав
Чтобы объединить независимо обученные картриджи в единый адаптер, используйте compose_cartridge_adapters(...).
API
CartridgeConfig
класс peft.CartridgeConfig
< source >( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falsenum_virtual_tokens: int = Nonetoken_dim: int = Nonenum_transformer_submodules: Optional[int] = Nonenum_attention_heads: Optional[int] = Nonenum_layers: Optional[int] = Nonemodules_to_save: Optional[list[str]] = Nonenum_frozen_tokens: int = 1 )
Параметры
- num_frozen_tokens (
int, по умолчанию 1) — Количество токенов префикса в начале картриджа, которые следует заморозить (без вычисления градиентов). Статья о Cartridges рекомендует замораживать первый токен в качестве attention sink для устойчивости (установите это значение в1), поскольку многие LLM используют начальные токены в качестве attention sink, и их изменение может навредить обучению.
Конфигурация для CARTRIDGE, префиксного адаптера с параметризованной KV-кэшем.
Это похоже на prefix-tuning по способу предоставления (в виде past_key_values), но кэш KV хранится непосредственно как обучаемые параметры, а не обучается через проекцию MLP.
Инициализация: В статье Cartridges обсуждается несколько вариантов инициализации. В PEFT инициализация является отдельным шагом от создания конфигурации адаптера:
Случайная инициализация KV (вариант 2 из статьи): создайте адаптер с помощью
get_peft_model(...). Параметры кодировщика промпта CARTRIDGE инициализируются случайно PyTorch.KV, полученные из первых токенов промпта/корпуса (вариант 3 из статьи): выполните prefill без градиентов на базовой модели и скопируйте первые
num_virtual_tokensкэшированных KV-токенов в адаптер. PEFT предоставляет утилиты для этого (импортируемые изpeftили изpeft.tuners.cartridge.utils):initialize_kv_prefix_from_text(model, tokenizer, text=...)initialize_kv_prefix_from_past_key_values(model, past_key_values=...)
Если у вас уже есть тензор с выровненным KV-префиксом, вы можете загрузить его напрямую с помощью метода
load_prompt_embeddings(...)кодировщика промпта.
CartridgeEncoder
Параметризованный префиксный кэш KV.
Параметры хранятся в том же плоском формате, что и вывод PrefixEncoder: `[num_virtual_tokens, num_layers
- 2 * token_dim]
, wheretoken_dimis per-head hidden size times number of heads (after any GQA adjustment performed by_prepare_prompt_learning_config`).
Если num_frozen_tokens > 0, первые num_frozen_tokens виртуальные токены сохраняются как необучаемый параметр, а остальные токены обучаемы.
Загрузите сглаженные эмбеддинги промпта, сохранённые PEFT (prompt_embeddings).
PEFT сохраняет адаптеры prompt-learning в виде единого тензора prompt_embeddings. Для CARTRIDGE мы разбиваем этот тензор на замороженные и обучаемые сегменты в соответствии с self.num_frozen_tokens.
initialize_kv_prefix_from_past_key_values
peft.initialize_kv_prefix_from_past_key_values
< source >( modeladapter_name: Optional[str] = Nonepast_key_values: Anynum_virtual_tokens: Optional[int] = None )
Инициализируйте адаптер обучения по префиксу KV из существующего кэшированного префикса (past_key_values).
Возвращает тензор эмбеддингов промпта, загруженный в адаптер.
prompt_embeddings_from_past_key_values
peft.prompt_embeddings_from_past_key_values
< source >( past_key_values: Anynum_virtual_tokens: int )
Преобразование (устаревшего) кэша past_key_values в тензор сглаженных эмбеддингов промпта, сохраняемый PEFT.
Вывод соответствует макету, ожидаемому PeftModel.get_prompt() для обучения промптов в префиксном стиле: форма [num_virtual_tokens, num_layers * 2 * token_dim].