Как использовать несколько адаптеров с предобученной моделью в Hugging Face Transformers для вывода?

Вопрос или проблема

У меня есть предобученная модель Llama-2 в директории models_hf и два адаптера с дообучением: адаптер для обобщения в ./tmp/llama-output и чат-адаптер в ./tmp/chat_adapter. Подробности кода находятся в другом вопросе.

Для вывода я хотел бы использовать все три компонента: предобученную модель, адаптер для обобщения и чат-адаптер. Однако я не уверен в требованиях к памяти и наилучшем подходе.

Мне нужно:

Вариант 1: Загрузить один экземпляр предобученной модели (например, 10 ГБ видеопамяти), а затем загрузить два отдельных экземпляра адаптеров (например, по 100 МБ каждый), что в итоге дает общее использование памяти 10 ГБ + 200 МБ?

ИЛИ

Вариант 2: Загрузить два отдельных экземпляра предобученной модели на 10 ГБ и совместить адаптер для обобщения на одном экземпляре и чат-адаптер на другом, что в итоге дает общее использование памяти 20 ГБ + 200 МБ?

Кроме того, не могли бы вы предоставить пример кода или шаги по загрузке и эффективному использованию этих компонентов для инференса? Я ищу руководство по управлению памятью и процессами загрузки, чтобы обеспечить плавный и эффективный инференс с этой настройкой.

Кажется, кто-то исправил эту проблему, просто замените модели изображений на языковые модели. Но я надеюсь на лучшие решения.

https://github.com/huggingface/peft/blob/main/examples/lora_dreambooth/lora_dreambooth_inference.ipynb

Ответ или решение

Конечно! Давайте разберемся, как использовать несколько адаптеров с предварительно обученной моделью в библиотеке Hugging Face Transformers для выполнения инференса. Мы рассмотрим, как правильно управлять памятью, а также приведем пример кода для эффективной загрузки и использования всех компонентов.

Введение

Использование адаптеров в Hugging Face Transformers позволяет интегрировать специализированные возможности в предварительно обученные модели, такие как Llama-2, благодаря чему можно адаптировать модель к конкретным задачам, не переобучая её целиком. Вы имеете адаптеры для обобщения и ведения диалога, размещенные в разных директориях. Следовательно, стоит рассмотреть два основных подхода к загрузке этих компонентов.

Варианты загрузки

  1. Вариант 1: Загрузить одну инстанцию предварительно обученной модели (например, 10ГБ GPU-памяти) и две отдельные инстанции адаптеров (по 100МБ каждая), что в сумме даст около 10ГБ + 200МБ. Это оптимальный способ по использованию памяти и подходит для задач, где вы хотите адаптировать модель под разные условия.

  2. Вариант 2: Загрузить две отдельные инстанции 10ГБ модели и присоединить адаптеры к каждой из них, что в итоге составит 20ГБ + 200МБ. Такой подход может потребовать больше ресурсов и неэффективен, если вы хотите запускать обе адаптации параллельно, так как возможно существование конфликта между моделями и риск потерять соотношение цена-качество по части памяти.

Рекомендации по использованию памяти

Наилучший вариант — использовать Вариант 1, так как он более экономичный. Одна инстанция модели позволяет оптимально управлять памятью и снизить нагрузку на GPU. При этом вы сможете переключаться между адаптерами без необходимости загружать модель повторно.

Пример кода

Далее приведён пример кода, как это можно реализовать с помощью библиотеки Hugging Face Transformers:

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel

# Загружаем базовую модель
model_name = "models_hf/llama-2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# Загружаем адаптеры
summarization_adapter = PeftModel.from_pretrained(model, "./tmp/llama-output")
chat_adapter = PeftModel.from_pretrained(model, "./tmp/chat_adapter")

# Функция для выполнения инференса с определенным адаптером
def inference_with_adapter(adapter, input_text):
    # Устанавливаем активный адаптер
    model.set_adapter(adapter)

    # Кодируем входной текст
    inputs = tokenizer(input_text, return_tensors="pt")

    # Выполняем инференс
    outputs = model.generate(**inputs)

    # Раскодируем вывод
    return tokenizer.decode(outputs[0], skip_special_tokens=True)

# Пример использования
input_summary = "Текст для обобщения."
result_summary = inference_with_adapter(summarization_adapter, input_summary)
print("Резюме:", result_summary)

input_chat = "Привет, как дела?"
result_chat = inference_with_adapter(chat_adapter, input_chat)
print("Чат:", result_chat)

Заключение

При использовании адаптеров с предварительно обученной моделью в Hugging Face Transformers, оптимальным решением будет загрузка единственной инстанции модели с несколькими адаптерами. Это поможет сэкономить ресурсы и улучшить производительность. Следование приведенному коду позволит вам эффективно управлять памятью и использовать адаптеры для выполнения различных задач, обеспечивая при этом высокую производительность.

Если у вас возникнут дополнительные вопросы по реализации или оптимизации, пожалуйста, дайте знать!

Оцените материал
Добавить комментарий

Капча загружается...