Unsloth руководство по наборам данных¶
Узнайте, как создать и подготовить набор данных для точной настройки.
Что такое набор данных?¶
Для LLM наборы данных - это данные, которые можно использовать для обучения наших моделей. Чтобы они были полезны для обучения, текстовые данные должны быть в формате, который можно использовать для разметки. Вы также можете изучить, как использовать наборы данных в Unsloth.
Одна из ключевых частей создания набора данных - это ваш шаблон чата и то, как вы собираетесь его оформить. Токенизация также важна, поскольку она разбивает текст на токены, которые могут быть словами, вложенными словами или символами, чтобы LLM могли эффективно его обрабатывать. Затем эти токены преобразуются во вложения и корректируются таким образом, чтобы помочь модели понять значение и контекст.
Формат данных¶
Чтобы включить процесс токенизации, наборы данных должны быть в формате, доступном для чтения токенизатором.
| Формат | Описание | Тип обучения |
|---|---|---|
| Необработанный корпус(Raw Corpus) | Необработанный текст из такого источника, как веб-сайт, книга или статья. | Непрерывная предварительная подготовка (CPT) |
| Инструкция(Instruct) | Инструкции для модели, которой следует следовать, и пример результата, к которому следует стремиться. | Контролируемая тонкая настройка (SFT) |
| Общение/диалог(Conversation) | Диалог между пользователем и ассистентом с искусственным интеллектом в несколько поворотов. | Контролируемая тонкая настройка (SFT) |
| RLHF | Диалог между пользователем и ассистентом с искусственным интеллектом, при этом ответы ассистента оцениваются сценарием, другой моделью или человеком-оценщиком. | Reinforcement Learning (RL) |
Стоит отметить, что для каждого из этих типов существуют разные стили оформления.
Getting Started¶
Прежде чем мы отформатируем наши данные, мы хотим определить следующее:
-
Назначение набора данных
Знание назначения набора данных поможет нам определить, какие данные нам нужны и в каком формате их использовать. Целью может быть адаптация модели к новой задаче, такой как обобщение или улучшение способности модели играть роль определенного персонажа. Например: - Диалоги в чате (вопросы и ответы, изучение нового языка, поддержка клиентов, беседы). - Структурированные задачи (классификация, обобщение, генерация задач). - Данные, относящиеся к конкретной предметной области (медицинские, финансовые, технические).
-
Стиль вывода
Стиль вывода позволит нам узнать, какие источники данных мы будем использовать для получения желаемого результата. Например, тип вывода, который вы хотите получить, может быть JSON, HTML, текст или код. Или, возможно, вы хотите, чтобы это был испанский, английский или немецкий и т.д.
-
Источник данных
Когда мы знаем назначение и стиль данных, которые нам нужны, нам нужно проанализировать качество и количество данных. Hugging Face и Википедия - отличные источники наборов данных, и Википедия особенно полезна, если вы хотите обучить модель изучению языка.
Источником данных может быть CSV-файл, PDF-файл или даже веб-сайт. Вы также можете генерировать данные синтетическим способом, но требуется особая осторожность, чтобы убедиться, что каждый пример является высококачественным и актуальным.
Один из лучших способов создать более качественный набор данных - это объединить его с более обобщенным набором данных от Hugging Face, таким как ShareGPT, чтобы сделать вашу модель умнее и разнообразнее. Вы также можете добавить синтетически сгенерированные данные.
Форматирование данных¶
Когда мы определим соответствующие критерии и соберем необходимые данные, мы сможем отформатировать наши данные в машиночитаемый формат, готовый для обучения.
Распространенные форматы данных для обучения LLM¶
Для дальнейшей предварительной подготовки мы используем необработанный текстовый формат без определенной структуры:
"text": "Pasta carbonara is a traditional Roman pasta dish. The sauce is made by mixing raw eggs with grated Pecorino Romano cheese and black pepper. The hot pasta is then tossed with crispy guanciale (cured pork cheek) and the egg mixture, creating a creamy sauce from the residual heat. Despite popular belief, authentic carbonara never contains cream or garlic. The dish likely originated in Rome in the mid-20th century, though its exact origins are debated..."
Этот формат сохраняет естественный поток речи и позволяет модели учиться на основе непрерывного текста.
Если мы адаптируем модель к новой задаче и хотим, чтобы модель выводила текст за один оборот на основе определенного набора инструкций, мы можем использовать формат инструкций в стиле Альпака
"Instruction": "Task we want the model to perform."
"Input": "Optional, but useful, it will essentially be the user's query."
"Output": "The expected result of the task and the output of the model."
Если нам нужно несколько вариантов обсуждения, мы можем использовать формат ShareGPT:
{
"conversations": [
{
"from": "human",
"value": "Can you help me make pasta carbonara?"
},
{
"from": "gpt",
"value": "Would you like the traditional Roman recipe, or a simpler version?"
},
{
"from": "human",
"value": "The traditional version please"
},
{
"from": "gpt",
"value": "The authentic Roman carbonara uses just a few ingredients: pasta, guanciale, eggs, Pecorino Romano, and black pepper. Would you like the detailed recipe?"
}
]
}
Формат шаблона использует ключи атрибутов "from"/"value", а сообщения чередуются между human и gpt, что обеспечивает естественный диалог.
Другим распространенным форматом является формат OpenAI ChatML, который используется по умолчанию для Hugging Face. Это, вероятно, наиболее часто используемый формат, в котором user и assistant чередуются
{
"messages": [
{
"role": "user",
"content": "What is 1+1?"
},
{
"role": "assistant",
"content": "It's 2!"
},
]
}
Применение шаблонов чата с помощью Unsloth¶
Для наборов данных, которые обычно соответствуют распространенному формату chatml, процесс подготовки набора данных к обучению или окончательной настройке состоит из четырех простых шагов:
-
Проверьте шаблоны чатов, которые в настоящее время поддерживает Unsloth:
from unsloth.chat_templates import CHAT_TEMPLATES print(list(CHAT_TEMPLATES.keys()))В результате будет распечатан список шаблонов, которые в настоящее время поддерживаются Unsloth. Вот пример вывода:
['unsloth', 'zephyr', 'chatml', 'mistral', 'llama', 'vicuna', 'vicuna_old', 'vicuna old', 'alpaca', 'gemma', 'gemma_chatml', 'gemma2', 'gemma2_chatml', 'llama-3', 'llama3', 'phi-3', 'phi-35', 'phi-3.5', 'llama-3.1', 'llama-31', 'llama-3.2', 'llama-3.3', 'llama-32', 'llama-33', 'qwen-2.5', 'qwen-25', 'qwen25', 'qwen2.5', 'phi-4', 'gemma-3', 'gemma3'] -
Используйте get_chat_template, чтобы применить правильный шаблон чата к вашему токенизатору:
from unsloth.chat_templates import get_chat_template tokenizer = get_chat_template( tokenizer, chat_template = "gemma-3", # измените это значение на правильное имя chat_template ) -
Определите свою функцию форматирования. Вот пример:
def formatting_prompts_func(examples): convos = examples["conversations"] texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False) for convo in convos] return { "text" : texts, }
Эта функция выполняет циклический просмотр вашего набора данных, применяя к каждой выборке определенный вами шаблон чата.
-
Наконец, давайте загрузим набор данных и внесем необходимые изменения в наш набор данных:
# Импорт и загрузка набора данных from datasets import load_dataset dataset = load_dataset("repo_name/dataset_name", split = "train") # Примените функцию форматирования к вашему набору данных, используя метод карты dataset = dataset.map(formatting_prompts_func, batched = True,)
Если в вашем наборе данных используется формат ShareGPT с ключами "from"/"value" вместо формата ChatML "role"/"content", вы можете сначала преобразовать его с помощью функции standardize_sharegpt. Измененный код теперь будет выглядеть следующим образом:
```
# Импорт набора данных
from datasets import load_dataset
dataset = load_dataset("mlabonne/FineTome-100k", split = "train")
# При необходимости преобразуйте ваш набор данных в формат "role"/"content"
from unsloth.chat_templates import standardize_sharegpt
dataset = standardize_sharegpt(dataset)
# Примените функцию форматирования к вашему набору данных, используя метод карты
dataset = dataset.map(formatting_prompts_func, batched = True,)
```
Вопросы и ответы по форматированию данных¶
Q: Как я могу использовать формат инструкций Alpaca?
A: Если ваш набор данных уже отформатирован в формате Alpaca, выполните действия по форматированию, как показано в Llama3.1 notebook. Если вам нужно преобразовать ваши данные в формат Alpaca, одним из подходов является создание скрипта на Python для обработки исходных данных. Если вы работаете над задачей обобщения, вы можете использовать локальный LLM для создания инструкций и выходных данных для каждого примера.
Q: Должен ли я всегда использовать метод standardize_sharegpt?
A: Используйте метод standardize_sharegpt только в том случае, если ваш целевой набор данных отформатирован в формате sharegpt, но ваша модель ожидает формат ChatML.
Q: Почему бы не использовать функцию apply_chat_template, которая поставляется с токенизатором.
A: Атрибут chat_template, который используется при первой загрузке модели первоначальными владельцами, иногда содержит ошибки, и для обновления может потребоваться время. В отличие от этого, в Unsloth мы тщательно проверяем и исправляем любые ошибки в chat_template для каждой модели, когда загружаем количественные версии в наши хранилища. Кроме того, наши методы get_chat_template и apply_chat_template предоставляют расширенные возможности манипулирования данными, которые полностью описаны на странице документации по шаблонам чата.
Q: Что делать, если мой шаблон в настоящее время не поддерживается Unsloth?
A: Отправьте запрос на добавление новой функции на форуме unsloth github issues. В качестве временного решения вы также можете использовать собственную функцию apply_chat_template токенизатора, пока ваш запрос на добавление новой функции не будет одобрен и объединен.
Генерация синтетических данных¶
Вы также можете использовать любой локальный LLM, например Llama 3.3 (70B) или OpenAI GPT 4.5, для создания синтетических данных. Как правило, лучше использовать Llama 3.3 (70B), чтобы обеспечить высочайшее качество результатов. Вы можете напрямую использовать механизмы логического вывода, такие как vLLM, Ollama или llama.cpp для создания синтетических данных, но для их сбора и запроса дополнительных данных потребуется некоторая ручная работа. У синтетических данных есть 3 цели:
-
Создание совершенно новых данных - либо с нуля, либо из существующего набора данных
-
Разнообразьте свой набор данных, чтобы ваша модель не перегружалась и не становилась слишком специфичной
-
Дополните существующие данные, например, автоматически структурируйте свой набор данных в правильном выбранном формате
Synthetic Dataset Notebook¶
В сотрудничестве с Meta мы запустили бесплатный notebook для автоматического создания синтетических наборов данных с использованием локальных моделей, таких как Llama 3.2. Доступ к notebook можно получить здесь.
Что делает блокнот:
- Автоматически анализирует PDF-файлы, веб-сайты, видео на YouTube и многое другое
- Использует набор синтетических данных Meta + Llama 3.2 (3B) для создания пар контроля качества
- Автоматически очищает и фильтрует данные
- Настраивает набор данных с помощью Unsloth + Llama
- Работа с записной книжкой полностью выполняется локально без необходимости вызова API
Использование локального LLM или ChatGPT для получения синтетических данных¶
Ваша цель - предложить модели сгенерировать и обработать данные контроля качества в указанном вами формате. Модели необходимо будет изучить предоставленную вами структуру, а также контекст, поэтому убедитесь, что у вас уже есть как минимум 10 примеров данных. Примеры запросов:
- Prompt на создание дополнительного диалога по существующему набору данных:
Using the dataset example I provided, follow the structure and generate conversations based on the examples. - Prompt если у вас нет набора данных:
Create 10 examples of product reviews for Coca-Coca classified as either positive, negative, or neutral. - Prompt для набора данных без форматирования:
Structure my dataset so it is in a QA ChatML format for fine-tuning. Then generate 5 synthetic data examples with the same topic and format.
Рекомендуется проверять качество сгенерированных данных, чтобы удалять или улучшать нерелевантные или некачественные ответы. В зависимости от вашего набора данных его также может потребоваться сбалансировать во многих областях, чтобы ваша модель не перегружалась. Затем вы можете отправить этот очищенный набор данных обратно в свой LLM для восстановления данных, теперь с еще большим количеством инструкций.
Часто задаваемые вопросы по набору данных + советы¶
Насколько большим должен быть мой набор данных?¶
Как правило, мы рекомендуем использовать как минимум 100 строк данных для точной настройки, чтобы получить приемлемые результаты. Для оптимальной производительности предпочтителен набор данных, содержащий более 1000 строк, и в этом случае большее количество данных обычно приводит к лучшим результатам. Если ваш набор данных слишком мал, вы также можете добавить синтетические данные или добавить набор данных из Hugging Face, чтобы разнообразить его. Однако эффективность вашей точно настроенной модели в значительной степени зависит от качества набора данных, поэтому обязательно тщательно очистите и подготовьте свои данные.
Как мне следует структурировать свой набор данных, если я хочу точно настроить логическую модель?¶
Если вы хотите точно настроить модель, в которой уже есть возможности логического анализа, такие как дистиллированные версии DeepSeek-R1 (например, DeepSeek-R1-Distill-Llama-8B), вам все равно нужно будет следовать парам вопрос / задание и ответ, однако для вашего ответа вам нужно будет изменить ответ таким образом, чтобы она включает в себя процесс рассуждения / цепочку размышлений и шаги, которые были предприняты для получения ответа.
Для модели, у которой нет логического обоснования, и вы хотите обучить ее так, чтобы впоследствии она могла использовать логические способности, вам нужно будет использовать стандартный набор данных, но на этот раз без логических обоснований в своих ответах. Этот процесс обучения известен как обучение с подкреплением и GRPO.
Несколько наборов данных¶
Если у вас есть несколько наборов данных для точной настройки, вы можете:
-
Стандартизируйте формат всех наборов данных, объедините их в единый набор данных и выполните точную настройку на основе этого единого набора данных.
-
Используйте notebook "Несколько наборов данных" для прямой настройки нескольких наборов данных.
Могу ли я точно настроить одну и ту же модель несколько раз?¶
Вы можете многократно корректировать уже отлаженную модель, но лучше всего объединить все наборы данных и выполнить тонкую настройку в рамках одного процесса. Обучение уже отлаженной модели потенциально может повлиять на качество и знания, полученные в ходе предыдущего процесса тонкой настройки.
Использование наборов данных в Unsloth¶
Alpaca Dataset¶
Смотрите пример использования набора данных Alpaca внутри Unsloth в Google Colab:

Теперь мы будем использовать набор данных Alpaca, созданный самим вызовом GPT-4. Это список из 52 000 инструкций и выходных данных, который был очень популярен, когда была выпущена Llama-1, поскольку благодаря ему finetuning базового LLM стал конкурентоспособным по сравнению с самим ChatGPT.
Вы можете получить доступ к GPT4-версии набора данных Alpaca здесь. Ниже приведены некоторые примеры набора данных:

Вы можете видеть, что в каждой строке есть по 3 столбца - инструкция, а также ввод и вывод. По сути, мы объединяем каждую строку в одно большое приглашение, как показано ниже. Затем мы используем это для точной настройки языковой модели, и это делает ее очень похожей на ChatGPT. Мы называем этот процесс точной настройкой контролируемых инструкций.

Несколько колонок для точной настройки¶
Но большая проблема заключается в том, что для помощников в стиле ChatGPT мы разрешаем только 1 инструкцию / 1 приглашение, а не несколько столбцов / входных данных. Например, в ChatGPT вы можете видеть, что мы должны отправлять 1 приглашение, а не несколько промптов.

По сути, это означает, что мы должны "объединить" несколько столбцов в одно большое приглашение, чтобы настройка действительно заработала!
Например, в очень известном наборе данных Titanic много-много столбцов. Ваша задача состояла в том, чтобы предсказать, выжил пассажир или умер, исходя из его возраста, класса обслуживания, стоимости проезда и т.д. Мы не можем просто передать это в чат, а должны "объединить" эту информацию в одно большое приглашение.

Например, если мы запросим ChatGPT с помощью нашего "объединенного" единого запроса, который содержит всю информацию об этом пассажире, мы можем попросить его угадать или предсказать, умер пассажир или выжил.

Другие библиотеки точной настройки требуют, чтобы вы вручную подготовили свой набор данных для точной настройки, объединив все столбцы в одно приглашение. В Unsloth мы просто предоставляем функцию to_sharegpt, которая делает это за один раз!

Теперь это немного сложнее, поскольку мы допускаем множество настроек, но есть несколько моментов:
-
Вы должны заключить все столбцы в фигурные скобки
{}. Это имена столбцов в самом файле CSV / Excel. -
Необязательные текстовые компоненты должны быть заключены в
[[]]. Например, если столбец "входные данные" пуст, функция объединения не отобразит текст и пропустит его. Это полезно для наборов данных с отсутствующими значениями. -
Выберите столбец
outputилиtarget/predictionв полеoutput_column_name. Для набора данных Alpaca это будетoutput.
Например, в наборе данных Titanic мы можем создать большой объединенный формат подсказок, как показано ниже, где каждый столбец / фрагмент текста становится необязательным.

Например, представьте, что набор данных выглядит следующим образом с большим количеством отсутствующих данных:
| Embarked | Age | Fare |
|---|---|---|
| S | 23 | |
| 18 | 7.25 |
Тогда мы не хотим, чтобы результат был таким:
-
Пассажир сел на рейс из пункта S. Ему 23 года. У него ПУСТОЙ билет.
-
Пассажир сел на рейс с ПУСТЫМ рейсом. Ему 18 лет. Стоимость проезда составляет 7,25 долларов.
Вместо этого, при желании, мы можем полностью исключить эту информацию, добавив в столбцы [[]].
-
[[Пассажир сел на рейс из S.]] [[Его возраст - 23 года.]] [[Их тариф не указан.]]
-
[[Пассажир сел в самолет ПОРОЖНИМ.]] [[Ему 18 лет.]] [[Стоимость проезда составляет 7,25 долларов.]]
становится:
-
Пассажир прибыл из С. Ему 23 года.
-
Ему 18 лет. Cтоимость проезда составляет 7,25 доллара.
Многооборотные разговоры¶
Небольшая проблема, если вы не заметили, заключается в том, что набор данных Alpaca представлен в один оборот, в то время как использование ChatGPT было интерактивным, и вы могли общаться с ним в несколько оборотов. Например, левый вариант - это то, что нам нужно, но правый, то есть набор данных Alpaca, предоставляет только отдельные разговоры. Мы хотим, чтобы точно настроенная языковая модель каким-то образом научилась вести многооборотные разговоры, как в ChatGPT.

Итак, мы ввели параметр conversation_extension, который, по сути, выбирает несколько случайных строк в вашем наборе данных и объединяет их в 1 диалог! Например, если вы установите для него значение 3, мы случайным образом выберем 3 строки и объединим их в 1! Слишком длинная настройка может замедлить обучение, но может значительно улучшить работу вашего чат-бота и финальную настройку finetune!

Затем задайте значение output_column_name для столбца прогнозирования / вывода. Для набора данных Alpaca это будет выходной столбец.
Затем мы используем функцию standardize_sharegpt, чтобы просто преобразовать набор данных в правильный формат для точной настройки! Всегда вызывайте это!

Vision Fine-tuning¶
Набор данных для точной настройки зрения или мультимодальной модели также включает в себя ввод изображений. Например, в Llama 3.2 Vision Notebook используется рентгенографический кейс, чтобы показать, как искусственный интеллект может помочь медицинским работникам более эффективно анализировать рентгеновские снимки, компьютерную томографию и ультразвук.
Мы будем использовать выборочную версию набора данных рентгенографии ROCO. Вы можете получить доступ к набору данных здесь. Набор данных включает рентгеновские снимки, компьютерную томографию и ультразвуковое исследование, демонстрирующие медицинские условия и заболевания. К каждому изображению есть подпись, написанная экспертами с описанием. Цель состоит в том, чтобы точно настроить VLM, чтобы сделать его полезным инструментом анализа для медицинских работников.
Давайте взглянем на набор данных и проверим, что показывает первый пример:
Dataset({
features: ['image', 'image_id', 'caption', 'cui'],
num_rows: 1978
})
| Image | Caption |
|---|---|
![]() |
Panoramic radiography shows an osteolytic lesion in the right posterior maxilla with resorption of the floor of the maxillary sinus (arrows). |
Чтобы отформатировать набор данных, все задачи точной настройки Vision должны быть отформатированы следующим образом:
[
{ "role": "user",
"content": [{"type": "text", "text": instruction}, {"type": "image", "image": image} ]
},
{ "role": "assistant",
"content": [{"type": "text", "text": answer} ]
},
]
Мы разработаем специальную инструкцию, в которой попросим VLM стать опытным рентгенологом. Обратите внимание, что вместо одной инструкции вы можете добавить несколько поворотов, чтобы сделать беседу динамичной.
instruction = "You are an expert radiographer. Describe accurately what you see in this image."
def convert_to_conversation(sample):
conversation = [
{ "role": "user",
"content" : [
{"type" : "text", "text" : instruction},
{"type" : "image", "image" : sample["image"]} ]
},
{ "role" : "assistant",
"content" : [
{"type" : "text", "text" : sample["caption"]} ]
},
]
return { "messages" : conversation }
pass
Давайте преобразуем набор данных в "правильный" формат для точной настройки:
converted_dataset = [convert_to_conversation(sample) for sample in dataset]
Первый пример теперь структурирован следующим образом:
converted_dataset[0]
{'messages': [{'role': 'user',
'content': [{'type': 'text',
'text': 'You are an expert radiographer. Describe accurately what you see in this image.'},
{'type': 'image',
'image': <PIL.PngImagePlugin.PngImageFile image mode=L size=657x442>}]},
{'role': 'assistant',
'content': [{'type': 'text',
'text': 'Panoramic radiography shows an osteolytic lesion in the right posterior maxilla with resorption of the floor of the maxillary sinus (arrows).'}]}]}
Прежде чем мы приступим к какой-либо точной настройке, возможно, модель vision уже знает, как анализировать изображения? Давайте проверим, так ли это на самом деле!
FastVisionModel.for_inference(model) # Enable for inference!
image = dataset[0]["image"]
instruction = "You are an expert radiographer. Describe accurately what you see in this image."
messages = [
{"role": "user", "content": [
{"type": "image"},
{"type": "text", "text": instruction}
]}
]
input_text = tokenizer.apply_chat_template(messages, add_generation_prompt = True)
inputs = tokenizer(
image,
input_text,
add_special_tokens = False,
return_tensors = "pt",
).to("cuda")
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer, skip_prompt = True)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128,
use_cache = True, temperature = 1.5, min_p = 0.1)
И каков же результат:
This radiograph appears to be a panoramic view of the upper and lower dentition, specifically an Orthopantomogram (OPG).
* The panoramic radiograph demonstrates normal dental structures.
* There is an abnormal area on the upper right, represented by an area of radiolucent bone, corresponding to the antrum.
**Key Observations**
* The bone between the left upper teeth is relatively radiopaque.
* There are two large arrows above the image, suggesting the need for a closer examination of this area. One of the arrows is in a left-sided position, and the other is in the right-sided position. However, only
Более подробную информацию можно найти в разделе с набором данных в notebook по ссылке.
