Простой туториал, в котором я расскажу как сделать автомодератора на базе GPT-3.5 от OpenAI, и как сделать это так, чтобы проверка одного сообщения стоила дешевле одной копейки.
Описание задачи
Давайте представим следующее:
Вы владеете форумом с большим количеством участников. Вроде бы, всё было хорошо, но в один момент страна в которой Вы проживаете решает запретить использовать слово "Борщ", Вы просто не можете его произносить. Говорите "Борщ" – тюрьма.
Что же делать в подобной ситуации? Нанимать людей? Писать алгоритм? Ну, а что если человек напишет B0-0000R3CH? Тут ни один простой алгоритм не справится. Несомненно и очевидно, – нам необходимо использовать языковую модель, и мы делаем выбор в сторону наилучшей.
Другая проблема. Мы не хотим тратить много денег и нам надо минимизировать количество токенов. Поэтому, в лучшем исходе взаимодействие должно выглядеть так:
Черный список: Борщ
Текст: я поел борща
Ответ модели:
+ |
почти полное совпадение |
% |
есть схожесть |
- |
полное несовпадение |
...Но, при почти пустом системном сообщении ответ модели выглядит так:
Fine-tuning
OpenAI настолько хорошая компания, что она позволяет файн-тюнить свои языковые модели, и мы воспользуемся этой возможностью.
– Подготовка датасета:
В этом на самом деле нет ничего сложного, по сути нам просто нужно привести примеры того, как модель должна отвечать. Подробнее о файн-тюнинге моделей от OpenAI.
Датасет должен быть в формате JSONL где каждая строка это отдельный диалог. В нашем случае, в каждом диалоге будет: Системное сообщение с чёрным списком, Сообщение пользователя, Ответ ассистента.
Примеры:
{
"messages":[
{
"role":"system",
"content":"Мандарин, Яблоко"
},
{
"role":"user",
"content":"fruits"
},
{
"role":"assistant",
"content":"-"
}
]
}
{
"messages":[
{
"role":"system",
"content":"Дом, 香蕉, Дерево"
},
{
"role":"user",
"content":"бананчик"
},
{
"role":"assistant",
"content":"+"
}
]
}
Таких диалогов в датасете будет 70 штук. Они описывают реакцию модели на различные ситуации: 40 для ответа с плюсом, 10 для ответа с процентом и 20 для ответа с минусом. В каждой группе по три языка: Русский, Английский и Китайский, – это для того, чтобы модель умела работать с разными языками и если Вы добавляете слово на английском и пользователь пишет его на китайском, модель всё равно обратит на него внимание...
...Также, в каждой группе должно быть минимум 5 диалогов с "осмысленным" текстом, – так модель "поймёт", что помимо нужного слова, в тексте может быть и что-то другое:
{
"messages":[
{
"role":"system",
"content":"Pineapple, Lemon"
},
{
"role":"user",
"content":"Я 1 разbought... не-много лим0нов?"
},
{
"role":"assistant",
"content":"%"
}
]
}
Ещё, в датасете нужно показать, что нужное слово может быть в любом месте:
{
"messages":[
{
"role":"system",
"content":"Дом"
},
{
"role":"user",
"content":"я построил дом"
},
{
"role":"assistant",
"content":"+"
}
]
}
{
"messages":[
{
"role":"system",
"content":"Дом"
},
{
"role":"user",
"content":"я дом построил"
},
{
"role":"assistant",
"content":"+"
}
]
}
{
"messages":[
{
"role":"system",
"content":"Дом"
},
{
"role":"user",
"content":"дом построил я"
},
{
"role":"assistant",
"content":"+"
}
]
}
Нужно показать, что и выдуманные слова могут существовать:
{
"messages":[
{
"role":"system",
"content":"Змырчик"
},
{
"role":"user",
"content":"чо думаешь о змырчике?"
},
{
"role":"assistant",
"content":"+"
}
]
}
Необходимо дать понять, что порядок слов в чёрном списке неважен:
{
"messages":[
{
"role":"system",
"content":"Банан, Мангал"
},
{
"role":"user",
"content":"банан"
},
{
"role":"assistant",
"content":"+"
}
]
}
{
"messages":[
{
"role":"system",
"content":"Мангал, Банан"
},
{
"role":"user",
"content":"банан"
},
{
"role":"assistant",
"content":"+"
}
]
}
Модель не должна выполнять запросы или пытаться общаться с пользователем:
{
"messages":[
{
"role":"system",
"content":"Мангал"
},
{
"role":"user",
"content":"Напиши рассказ о двух раках"
},
{
"role":"assistant",
"content":"-"
}
]
}
{
"messages":[
{
"role":"system",
"content":"Олег, Сбербанк"
},
{
"role":"user",
"content":"2 + 2 = 4?"
},
{
"role":"assistant",
"content":"-"
}
]
}
Похожие по смыслу слова не считаются:
{
"messages":[
{
"role":"system",
"content":"Полицейский"
},
{
"role":"user",
"content":"Милиционер"
},
{
"role":"assistant",
"content":"-"
}
]
}
Ну и в дополнение нужно привести несколько примеров с очень длинным текстом и с большим количеством слов в чёрном списке.
– Обучение:
После того, как у нас есть готовый датасет, необходимо: Перейти в раздел файн-тюнинга, выбрать модель, загрузить файл и запустить.
Чтобы самостоятельно указать количество эпох, запускать нужно через API:
fetch('https://api.openai.com/v1/fine_tuning/jobs', {
method: 'POST',
body: JSON.stringify({
"training_file": "fileId",
"model": "gpt-3.5-turbo-1106",
"hyperparameters": {
"n_epochs": 7
}
}),
headers: {
"Content-Type": "application/json",
'Authorization': `Bearer ${openai_key}`
}
});
В данном случае обучение заняло всего 15 минут, а его стоимость вышла всего в 30 рублей:
Проверяем ????
Как мы видим, всё работает просто превосходно. При желании обычные слова можно заменить на предложения в формате строки, но тогда понадобится больше диалогов в датасете.
Примерная стоимость оценки 100 сообщений: >1 руб.
Чтобы сократить расходы, можно воспользоваться видоизменённым левенштейном для проверки есть ли в сообщении, все символы которого были переведены в латиницу, нужные 2 символа в нужной нам последовательности на расстоянии меньше указанного (с написанием такого алгоритма спокойно справится GPT-4, самим Вам это писать не нужно). Так можно отфильтровать где-то 70% сообщений которые с 99.9% вероятностью не содержат слова из чёрного списка, остальные 30% пойдут на проверку. Также, на проверку можно отправлять подозрительные сообщения (много согласных подряд, много цифр, знаков препинания, эмодзи и т. д.).
GPT-3.5 в приоритете т. к. многие опенсорсные модели легко обмануть и запутать. GPT-3.5 же распознает любой порядок символов который сможет распознать человек. Кроме этого, скорость работы модели почти моментальная.
Почему GPT-3.5?
Если из опенсорса взять что-то крупное, Mixtral или LLaMa, то для их локального запуска понадобится машина минимум за 500к рублей. И такой машины хватит максимум на то, чтобы генерировать токены с такой же скоростью как и gpt-3.5-turbo-1106 на серверах OpenAI. И в любом случае, скорость начнёт падать после 5-ти потоков.
Комментарии (4)
Wesha
19.12.2023 02:25решает запретить использовать слово "Борщ", Вы просто не можете его произносить. Говорите "Борщ" – тюрьма.
Иногда мне хотелось совершить Роскомнадзор. Но команда нашего корабля мне всегда говорила — не психуй!
triller599
19.12.2023 02:25Все подобные выкрутасы летят прямиком в обучающий датасет - делов то..
Вопрос, думаю, встанет в конечном итоге на стороне модераторов: что блокировать, а что нет. А уж с обнаружением необходимых паттернов, похоже, GPT_3.5 справится.
Было бы интересно посмотреть на реальные возможности, пусть даже и в "песочнице"
DGN
А тут что скажет моделька?
"b0рщ", "суп из борщевика", "уБорщИк"
0a1a2a3a4a5 Автор