Перейти до вмісту
> 💻 🧠 Код 1001 > 🧪📓 Без категорії > Персоналізація LLM: промпти, тонке налаштування моделей, приклади коду.

Персоналізація LLM: промпти, тонке налаштування моделей, приклади коду.

  • від

1. Як LLM “пам’ятає” та “підлаштовується”: Ілюзія контексту

Перш ніж говорити про тонке налаштування, важливо зрозуміти, як LLM взагалі вдається створювати відчуття персоналізації.
Це важливо, щоб не кидатися в дороге тонке налаштування, якщо завдання вирішується простішими способами:

  • Через Контекстне вікно (Short-Term Memory): У рамках одного діалогу ви надсилаєте моделі не лише нове запитання, а й всю або частину попереднього листування. Модель обробляє весь цей текст як єдиний “контекст”. Саме завдяки цьому вона “пам’ятає” попередні репліки та продовжує думку. Обмеження тут — довжина контекстного вікна (кількість токенів).
  • Складання Системних інструкцій (System Prompt): Ви можете задати моделі роль, тон, правила поведінки на початку кожного діалогу. Наприклад: “Ти – експерт з Python, відповідай коротко”.
  • Включення в запит кількох прикладів бажаної поведінки Few-Shot Learning: (пари вхід/вихід) дозволяє моделі “навчитися” цьому патерну прямо в рамках поточного запиту.
  • Керування станом на стороні програми: Найпотужніший спосіб. Програма (яка звертається до API) може зберігати інформацію про користувача (переваги, історію, дані профілю) та динамічно додавати її в промпт перед надсиланням моделі.

2. Навіщо і коли потрібне тонке налаштування (Fine-tuning) моделі.

Тонке налаштування – це процес донавчання вже готової базової LLM на вашому власному, специфічному наборі даних. Це дозволяє моделі:

  • Адаптувати стиль та тон: Модель буде говорити “вашою мовою” – будь то строгий науковий, доброзичливий маркетинговий або сленг певного співтовариства.
  • Дотримуватися специфічних інструкцій та форматів: Якщо вам потрібні відповіді в строго визначеній JSON-структурі, або завжди з певним набором полів.
  • Розуміти домен-специфічну мову: Навчання на вашій внутрішній документації або галузевих текстах допоможе моделі краще справлятися з термінологією вашої ніші.
  • Покращити продуктивність на вузьких завданнях: Для певних типів запитів (наприклад, класифікація відгуків, генерація коду в специфічному фреймворку) тонке налаштування може дати більш точні та релевантні відповіді, ніж базова модель.
  • Скоротити довжину промптів: Якщо модель вже “знає” бажану поведінку завдяки налаштуванню, вам не потрібно щоразу нагадувати їй про це в промпті, що економить токени та знижує затримку.

3. Коли тонке налаштування – не найкраще рішення.

Тонке налаштування – потужний, але не універсальний інструмент. Не варто використовувати його, якщо:

  • Модель повинна отримувати доступ до нових знань: Тонке налаштування змінює ваги моделі, але не “завантажує” в неї нові факти в реальному часі. Якщо ваше завдання – відповідати на запитання за постійно змінною базою знань (документи компанії, останні новини), краще використовувати Retrieval Augmented Generation (RAG). Тут базова модель отримує контекст з вашої бази даних під час виконання запиту.
  • Просте завдання вирішується промпт-інжинірингом: Завжди починайте з максимально ефективного промпт-інжинірингу. Якщо завдання вирішується простими інструкціями та few-shot прикладами, тонке налаштування надмірне та дорожче.
  • У вас немає достатньої кількості високоякісних даних: Погані дані = погано налаштована модель.

4. Підготовка даних.

Якість та кількість ваших даних є критично важливими. Модель навчається на ваших прикладах, тому вони повинні бути точними, різноманітними та послідовними.

  • Формат: Найчастіше JSON Lines (.jsonl) або CSV (.csv).
  • Структура даних: Залежить від завдання.
    • Instruction Tuning (Інструкція-Відповідь): Підходить для узагальнених завдань типу “питання-відповідь”, перефразування, узагальнення.
      json {"input_text": "Перефразуй речення: 'Технологія ШІ стрімко розвивається.'", "output_text": "Штучний інтелект демонструє стрімкий прогрес."} {"input_text": "Назви столицю Франції.", "output_text": "Столиця Франції — Париж."}
    • Chat Tuning (Чат): Ідеально для навчання моделі веденню діалогу в певній ролі або стилі.
      json {"messages": [{"author": "user", "content": "Привіт! Що порекомендуєш на вечерю?"}, {"author": "model", "content": "Добрий вечір! Сьогодні чудовий день для пасти Карбонара, або, якщо ви віддаєте перевагу чомусь легкому, салат Цезар."}]} {"messages": [{"author": "user", "content": "Розкажи про нові фічі в Python 3.12."}, {"author": "model", "content": "У Python 3.12 з'явилися f-рядки з відступами, новий синтаксис для універсальних генериків та покращена обробка помилок Unicode."}]}
  • Кількість: Мінімум 100-200 якісних прикладів, але чим більше, тим краще (тисячі для серйозних завдань).
  • Якість: Точність, послідовність стилю, тону, формату в усьому наборі даних.

5. Моделі та платформи

5.1. OpenAI

OpenAI надає досить простий та інтуїтивно зрозумілий API для тонкого налаштування.

Процес:

  1. Підготовка даних у форматі JSONL, де кожен рядок — це об’єкт з масивом messages (як у Chat Completions API).
  2. Завантаження файлу даних через API.
  3. Створення завдання на тонке налаштування, вказавши завантажений файл та базову модель.
  4. Відстеження прогресу.
  5. Використання нової, налаштованої моделі за її ID.

Приклад даних (файл training_data.jsonl):

{"messages": [{"role": "system", "content": "Ти - дружелюбний асистент з підтримки клієнтів IT-компанії."}, {"role": "user", "content": "Мій інтернет не працює."}, {"role": "assistant", "content": "Ох, вибачте за незручності! Давайте спробуємо розібратися. Яким чином ви підключені до інтернету – по Wi-Fi чи через кабель?"}]}
{"messages": [{"role": "system", "content": "Ти - дружелюбний асистент з підтримки клієнтів IT-компанії."}, {"role": "user", "content": "Як я можу скинути пароль?"}, {"role": "assistant", "content": "Звісно! Щоб скинути пароль, перейдіть, будь ласка, на сторінку входу та натисніть 'Забули пароль?' під полем для введення. Далі дотримуйтесь інструкцій на екрані."}]

Приклад Python коду:

Попередньо встановіть: pip install openai

import openai
from openai import OpenAI
import os

# Встановіть ваш API-ключ OpenAI. Рекомендується використовувати змінну середовища.
# os.environ["OPENAI_API_KEY"] = "sk-..."
client = OpenAI()

# 1. Завантаження файлу даних
try:
    file_response = client.files.create(
        file=open("training_data.jsonl", "rb"),
        purpose="fine-tune"
    )
    file_id = file_response.id
    print(f"Файл успішно завантажено. ID файлу: {file_id}")
except openai.APIStatusError as e:
    print(f"Помилка завантаження файлу: {e.status_code} - {e.response}")
    exit()

# 2. Створення завдання на тонке налаштування
try:
    ft_job_response = client.fine_tuning.jobs.create(
        training_file=file_id,
        model="gpt-3.5-turbo" # Можна вказати конкретну версію, наприклад, "gpt-3.5-turbo-0125"
    )
    job_id = ft_job_response.id
    print(f"Завдання на тонке налаштування створено. ID завдання: {job_id}")
    print("Відстежуйте статус завдання через API або в OpenAI Playground.")
except openai.APIStatusError as e:
    print(f"Помилка створення завдання: {e.status_code} - {e.response}")
    exit()

# Приклад відстеження статусу та отримання імені моделі (виконувати після створення завдання):
# # job_id = "ftjob-..." # Замініть на ID вашого завдання
# # job_status = client.fine_tuning.jobs.retrieve(job_id)
# # print(f"Поточний статус завдання: {job_status.status}")
# # if job_status.status == "succeeded":
# #     fine_tuned_model_name = job_status.fine_tuned_model
# #     print(f"Ім'я налаштованої моделі: {fine_tuned_model_name}")

# 3. Використання налаштованої моделі (після її готовності)
# # Замініть на реальне ім'я вашої моделі, отримане після успішного тонкого налаштування
# # fine_tuned_model_name = "ft:gpt-3.5-turbo-0125:my-org::abcd123"

# # if 'fine_tuned_model_name' in locals() and fine_tuned_model_name:
# #     try:
# #         response = client.chat.completions.create(
# #             model=fine_tuned_model_name,
# #             messages=[
# #                 {"role": "user", "content": "У мене проблема з логіном."}
# #             ]
# #         )
# #         print("\nВідповідь налаштованої моделі:")
# #         print(response.choices[0].message.content)
# #     except openai.APIStatusError as e:
# #         print(f"Помилка при використанні моделі: {e.status_code} - {e.response}")

5.2. Anthropic

Anthropic не надає публічного API для тонкого налаштування своїх моделей Claude 3 (Opus, Sonnet, Haiku) у тому ж сенсі, як це робить OpenAI або Google.

Anthropic зосереджений на створенні дуже потужних базових моделей, які, за їхніми твердженнями, чудово працюють з просунутим промпт-інжинірингом та RAG-патернами, мінімізуючи необхідність у тонкому налаштуванні для більшості випадків. Для великих корпоративних клієнтів або партнерів можуть існувати програми зі створення “кастомних” моделей або спеціалізованих інтеграцій, але це не є загальнодоступною функцією тонкого налаштування через API.

If you are working with Claude 3, your primary focus should be on:

  • High-quality prompt engineering: Experiment with system instructions, few-shot examples, clear request formatting. Claude is known for its ability to strictly follow instructions, especially in XML tags.
  • RAG systems: Use external knowledge bases to provide the model with relevant context.

5.3. Google (Gemini)

Google активно розвиває можливості тонкого налаштування через свою платформу Google Cloud Vertex AI. This is a full-fledged ML platform that provides tools for data preparation, running training jobs, and deploying models. Fine-tuning is available for the Gemini family of models.

Process:

  1. Prepare data (JSONL or CSV) in input_text/output_text format (for instruction tuning) or messages (for chat tuning).
  2. Upload data to Google Cloud Storage (GCS).
  3. Create and run a fine-tuning job via the Vertex AI Console or SDK.
  4. Deploy the fine-tuned model to an Endpoint.
  5. Use the fine-tuned model via this Endpoint.

Example data (file gemini_tuning_data.jsonl):

{"input_text": "Узагальни основні ідеї цієї книги: 'Книга розповідає про подорож героя, який долає перешкоди та знаходить себе.'", "output_text": "Головний герой книги вирушає в трансформаційну подорож, стикаючись з труднощами та здобуваючи самопізнання."}
{"input_text": "Поясни принцип роботи термоядерного реактора простими словами.", "output_text": "Термоядерний реактор намагається відтворити процес, що відбувається на Сонці: злиття легких атомних ядер при дуже високих температурах, вивільняючи величезну кількість енергії."}

Example Python code (потребує google-cloud-aiplatform):

Попередньо встановіть: pip install google-cloud-aiplatform та pip install google-cloud-storage

import os
from google.cloud import aiplatform
from google.cloud import storage

# --- Налаштування ---
# ЗАМІНІТЬ на свої значення:
PROJECT_ID = "your-gcp-project-id"
REGION = "us-central1"               # Виберіть регіон, що підтримує Gemini та Vertex AI
BUCKET_NAME = "your-gcs-bucket-for-tuning" # Ім'я вашого бакету GCS (має бути створений заздалегідь)
DATA_FILE_LOCAL_PATH = "gemini_tuning_data.jsonl"
GCS_DATA_URI = f"gs://{BUCKET_NAME}/{DATA_FILE_LOCAL_PATH}"
TUNED_MODEL_DISPLAY_NAME = "my-tuned-gemini-model"
# --- Кінець налаштувань ---

# Ініціалізація Vertex AI
aiplatform.init(project=PROJECT_ID, location=REGION)

# 1. Створення файлу з даними (якщо його немає)
with open(DATA_FILE_LOCAL_PATH, "w", encoding="utf-8") as f:
    f.write('{"input_text": "Узагальни основні ідеї цієї книги: \'Книга розповідає про подорож героя, який долає перешкоди та знаходить себе.\'", "output_text": "Головний герой книги вирушає в трансформаційну подорож, стикаючись з труднощами та здобуваючи самопізнання."}\n')
    f.write('{"input_text": "Поясни принцип роботи термоядерного реактора простими словами.", "output_text": "Термоядерний реактор намагається відтворити процес, що відбувається на Сонці: злиття легких атомних ядер при дуже високих температурах, вивільняючи величезну кількість енергії."}\n')
print(f"Файл даних '{DATA_FILE_LOCAL_PATH}' створено.")


# 2. Завантаження даних у Google Cloud Storage
def upload_blob(bucket_name, source_file_name, destination_blob_name):
    """Завантажує файл у бакет GCS."""
    storage_client = storage.Client(project=PROJECT_ID)
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(destination_blob_name)
    blob.upload_from_filename(source_file_name)
    print(f"Файл '{source_file_name}' завантажено в 'gs://{bucket_name}/{destination_blob_name}'.")

try:
    upload_blob(BUCKET_NAME, DATA_FILE_LOCAL_PATH, DATA_FILE_LOCAL_PATH)
except Exception as e:
    print(f"Помилка завантаження файлу в GCS. Переконайтеся, що бакет існує і у вас є права: {e}")
    exit()

# 3. Створення та запуск завдання на тонке налаштування
print(f"\nЗапуск тонкого налаштування моделі '{TUNED_MODEL_DISPLAY_NAME}'...")
try:
    # `tune_model` запускає завдання та повертає налаштовану модель після завершення
    tuned_model = aiplatform.Model.tune_model(
        model_display_name=TUNED_MODEL_DISPLAY_NAME,
        source_model_name="gemini-1.0-pro-001", # Базова модель Gemini Pro
        training_data_path=GCS_DATA_URI,
        tuning_method="SUPERVISED_TUNING",
        train_steps=100, # Кількість кроків навчання. Оптимальне значення залежить від розміру даних.
        # batch_size=16, # Можна вказати
        # learning_rate_multiplier=1.0 # Можна вказати
    )
    print(f"Модель '{TUNED_MODEL_DISPLAY_NAME}' успішно налаштована. ID моделі: {tuned_model.name}")
    print("Процес тонкого налаштування може зайняти значний час.")
except Exception as e:
    print(f"Помилка тонкого налаштування. Перевірте логи в Vertex AI Console: {e}")
    exit()

# 4. Розгортання налаштованої моделі (для використання)
print(f"\nРозгортання налаштованої моделі '{TUNED_MODEL_DISPLAY_NAME}' на кінцеву точку...")
try:
    endpoint = tuned_model.deploy(
        machine_type="n1-standard-4", # Тип машини для кінцевої точки. Виберіть відповідний.
        min_replica_count=1,
        max_replica_count=1
    )
    print(f"Модель розгорнута на кінцеву точку: {endpoint.name}")
    print("Розгортання також може зайняти кілька хвилин.")
except Exception as e:
    print(f"Помилка розгортання моделі: {e}")
    exit()

# 5. Використання налаштованої моделі
print("\nТестування налаштованої моделі...")
prompt = "Розкажи мені про свої можливості після навчання."
instances = [{"prompt": prompt}] # Для Instruction Tuning. Якщо Chat Tuning, то {"messages": [...]}

try:
    response = endpoint.predict(instances=instances)
    print("\nВідповідь налаштованої моделі:")
    print(response.predictions[0])
except Exception as e:
    print(f"Помилка при використанні налаштованої моделі: {e}")

# Після завершення роботи, не забудьте видалити кінцеву точку та модель, щоб уникнути зайвих витрат:
# endpoint.delete()
# tuned_model.delete()

6. Загальні рекомендації

  • Почніть з малого: Не намагайтеся відразу навчити модель на тисячах прикладів. Почніть з невеликого, але якісного набору даних.
  • Ітеруйте: Тонке налаштування — це ітераційний процес. Навчайте, оцінюйте, коригуйте дані або гіперпараметри, повторюйте.
  • Моніторинг: Уважно відстежуйте метрики навчання (втрати) та використовуйте набір валідаційних даних, щоб уникнути перенавчання.
  • Оцінка: Завжди тестуйте налаштовану модель на даних, які вона *ніколи не бачила* під час навчання, щоб оцінити її узагальнюючу здатність.
  • Вартість: Пам’ятайте, що тонке налаштування та розгортання кінцевих точок платні. Враховуйте це в бюджеті.
  • Документація: Завжди звіряйтеся з офіційною документацією постачальника LLM. API та можливості постійно розвиваються.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *