Transformers documentation

Генерация текста

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Генерация текста

Генерация текста — самое популярное применение больших языковых моделей (LLM). LLM обучается генерировать следующее слово (токен) на основе начального текста (промпта) и собственных ранее сгенерированных выходов до достижения заданной длины или токена конца последовательности (EOS).

В Transformers API generate() отвечает за генерацию текста и доступен для всех моделей с генеративными возможностями. В этом руководстве вы познакомитесь с основами генерации текста с помощью generate() и узнаете о типичных ошибках, которых следует избегать.

Для следующих команд убедитесь, что transformers serve запущен.

transformers chat Qwen/Qwen2.5-0.5B-Instruct

Генерация по умолчанию

Прежде чем начать, рекомендуется установить bitsandbytes для квантования очень больших моделей с целью снижения потребления памяти.

!pip install -U transformers bitsandbytes

Bitsandbytes поддерживает несколько бэкендов помимо CUDA-совместимых GPU. Подробнее см. в руководстве по установке с несколькими бэкендами.

Загрузите LLM с помощью from_pretrained() и добавьте следующие два параметра для снижения требований к памяти.

  • device_map="auto" включает функцию Big Model Inference в Accelerate, которая автоматически инициализирует каркас модели и загружает и распределяет веса модели по всем доступным устройствам, начиная с самого быстрого (GPU).
  • quantization_config — это объект конфигурации, определяющий параметры квантования. В данном примере в качестве бэкенда квантования используется bitsandbytes (см. раздел Quantization для списка доступных бэкендов), а модель загружается в режиме 4-bits.
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto", quantization_config=quantization_config)

Токенизируйте входные данные и установите параметр padding_side() в значение "left", так как LLM не обучена продолжать генерацию от токенов отсечки. Токенизатор возвращает идентификаторы входных данных и маску внимания.

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

tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
model_inputs = tokenizer(["A list of colors: red, blue"], return_tensors="pt").to(model.device)

Передайте входные данные в generate(), чтобы сгенерировать токены, а затем используйте batch_decode(), чтобы преобразовать сгенерированные токены обратно в текст.

generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
"A list of colors: red, blue, green, yellow, orange, purple, pink,"

Конфигурация генерации

Все параметры генерации содержатся в GenerationConfig. В примере выше параметры генерации берутся из файла generation_config.json модели mistralai/Mistral-7B-v0.1. Если с моделью не сохранена конфигурация, используется стратегия декодирования по умолчанию.

Осмотрите конфигурацию через атрибут generation_config. Он отображает только значения, отличающиеся от конфигурации по умолчанию, в данном случае это bos_token_id и eos_token_id.

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto")
model.generation_config
GenerationConfig {
  "bos_token_id": 1,
  "eos_token_id": 2
}

Вы можете настроить generate(), переопределив параметры и значения в GenerationConfig. См. раздел ниже для часто настраиваемых параметров.

# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)

generate() также можно расширить с помощью внешних библиотек или собственного кода:

  1. параметр logits_processor принимает пользовательские экземпляры LogitsProcessor для манипуляции распределением вероятностей следующего токена;
  2. Параметр stopping_criteria поддерживает пользовательские StoppingCriteria для остановки генерации текста;
  3. другие пользовательские методы генерации можно загрузить с помощью флага custom_generate (документация).

См. руководство Стратегии генерации, чтобы узнать больше о стратегиях поиска, выборки и декодирования.

Сохранение

Создайте экземпляр GenerationConfig и укажите нужные параметры декодирования.

from transformers import AutoModelForCausalLM, GenerationConfig

model = AutoModelForCausalLM.from_pretrained("my_account/my_model")
generation_config = GenerationConfig(
    max_new_tokens=50, do_sample=True, top_k=50, eos_token_id=model.config.eos_token_id
)

Используйте save_pretrained(), чтобы сохранить конкретную конфигурацию генерации, и установите параметр push_to_hub в True, чтобы загрузить её на Hub.

generation_config.save_pretrained("my_account/my_model", push_to_hub=True)

Оставьте параметр config_file_name пустым. Этот параметр следует использовать при хранении нескольких конфигураций генерации в одной директории. Он позволяет указать, какую именно конфигурацию генерации нужно загрузить. Вы можете создавать разные конфигурации для различных генеративных задач (креативная генерация текста с использованием сэмплинга, суммаризация с beam search) для использования с одной моделью.

from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, GenerationConfig

tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small")
model = AutoModelForSeq2SeqLM.from_pretrained("google-t5/t5-small")

translation_generation_config = GenerationConfig(
    num_beams=4,
    early_stopping=True,
    decoder_start_token_id=0,
    eos_token_id=model.config.eos_token_id,
    pad_token=model.config.pad_token_id,
)

translation_generation_config.save_pretrained("/tmp", config_file_name="translation_generation_config.json", push_to_hub=True)

generation_config = GenerationConfig.from_pretrained("/tmp", config_file_name="translation_generation_config.json")
inputs = tokenizer("translate English to French: Configuration files are easy to use!", return_tensors="pt")
outputs = model.generate(**inputs, generation_config=generation_config)
print(tokenizer.batch_decode(outputs, skip_special_tokens=True))

Общие параметры

generate() — это мощный инструмент, который можно сильно настроить. Для новых пользователей это может показаться сложным. В этом разделе приведен список популярных параметров генерации, которые можно задать в большинстве инструментов текстовой генерации в Transformers: generate(), GenerationConfig, pipelines, CLI chat, …

Название параметраТипУпрощенное описание
max_new_tokensintУправляет максимальной длиной генерации. Обязательно задайте это значение, так как по умолчанию оно обычно устанавливается на небольшой размер.
do_sampleboolОпределяет, будет ли генерация выбирать следующий токен методом выборки (True) или жадным алгоритмом (False). В большинстве случаев этот флаг следует установить в True. Подробнее см. в этом руководстве.
temperaturefloatНасколько непредсказуемым будет следующий выбранный токен. Высокие значения (>0.8) подходят для творческих задач, низкие значения (например, <0.4) — для задач, требующих «размышлений». Требуется do_sample=True.
num_beamsintПри значении >1 активируется алгоритм beam search. Beam search хорошо работает на задачах, привязанных к входным данным. Подробнее см. в этом руководстве.
repetition_penaltyfloatУстановите значение >1.0, если модель часто повторяет себя. Большие значения означают более сильный штраф.
eos_token_idlist[int]Токен(ы), которые приведут к остановке генерации. Значение по умолчанию обычно подходит, но вы можете указать другой токен.

Подводные камни

Раздел ниже описывает ряд типичных проблем, с которыми вы можете столкнуться при генерации текста, и способы их решения.

Длина вывода

generate() по умолчанию возвращает не более 20 токенов, если иное не указано в GenerationConfig модели. Настоятельно рекомендуется вручную задавать количество генерируемых токенов с помощью параметра max_new_tokens, чтобы контролировать длину вывода. Модели Decoder-only возвращают исходный промпт вместе с сгенерированными токенами.

model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to(model.device)
длина по умолчанию
max_new_tokens
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'A sequence of numbers: 1, 2, 3, 4, 5'

Стратегия декодирования

Стратегия декодирования по умолчанию в generate() — это жадкий поиск, который выбирает следующий наиболее вероятный токен, если в GenerationConfig модели не указано иное. Хотя эта стратегия хорошо работает для задач, основанных на входных данных (транскрипция, перевод), она не является оптимальной для более творческих сценариев использования (написание рассказов, чат-приложения).

Например, включите стратегию multinomial sampling, чтобы получать более разнообразные результаты. Дополнительные сведения о стратегиях декодирования см. в руководстве Generation strategy.

model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to(model.device)
жадный поиск
многономиальная выборка
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

Сторона отступов

Входные данные необходимо дополнять (padding), если их длины различаются. Однако LLM не обучены продолжать генерацию от токенов дополнения, поэтому параметр padding_side() должен быть установлен в значение left для входных данных. Правое дополнение хуже для рекуррентных и гибридных моделей, поскольку их рекуррентное состояние продолжает обновляться на хвостовых токенах дополнения, из-за чего кэш перестаёт соответствовать концу промпта.

правая отсечка
left pad
model_inputs = tokenizer(
    ["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 33333333333'

Формат запроса

Некоторые модели и задачи ожидают определённый формат входного промпта, и если формат неверен, модель возвращает неоптимальный результат. Подробнее о промптинге можно узнать в руководстве по инженерии промптов.

Например, чат-модель ожидает входные данные в формате шаблона чата. Ваш промпт должен содержать role и content, чтобы указать, кто участвует в разговоре. Если вы попытаетесь передать промпт как одну строку, модель не всегда вернёт ожидаемый результат.

from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")
model = AutoModelForCausalLM.from_pretrained(
    "HuggingFaceH4/zephyr-7b-alpha", device_map="auto", quantization_config=BitsAndBytesConfig(load_in_4bit=True)
)
no format
шаблон чата
prompt = """How many cats does it take to change a light bulb? Reply as a pirate."""
model_inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
input_length = model_inputs.input_ids.shape[1]
generated_ids = model.generate(**model_inputs, max_new_tokens=50)
print(tokenizer.batch_decode(generated_ids[:, input_length:], skip_special_tokens=True)[0])
"Aye, matey! 'Tis a simple task for a cat with a keen eye and nimble paws. First, the cat will climb up the ladder, carefully avoiding the rickety rungs. Then, with"

Ресурсы

Ниже представлены более специализированные библиотеки для генерации текста.

  • Optimum: расширение Transformers, ориентированное на оптимизацию обучения и инференса на конкретных аппаратных устройствах
  • Outlines: библиотека для генерации текста с ограничениями (например, генерация файлов JSON).
  • SynCode: библиотека для генерации, управляемой контекстно-свободной грамматикой (JSON, SQL, Python).
  • Text Generation Inference: готовый к работе в продакшене сервер для LLM.
  • Text generation web UI: веб-интерфейс на Gradio для генерации текста.
  • logits-processor-zoo: дополнительные logits-процессоры для управления генерацией текста.
Update on GitHub