Думаю, все уже наслышаны о потрясающих возможностях ChatGPT и GPT-3, многие уже вдоволь наигрались с ними, а новые стартапы на их основе льются на нас каждый день проливным дождём! Возможности ChatGPT в решении некоторых текстовых задач потрясают, порой кажется, что имеешь дело с настоящим разумом.
У меня возникла идея - что если попробовать доучить сеть так, чтобы она имитировала картину мира определенного человека? (Да, снова Черное Зеркало). Классический подход с pre-prompt для этого не подходит, так как хочется заложить в сеть побольше знаний (а также реально поменять веса связей), поэтому будем использовать fine-tune (дообучение на небольшом датасете и небольшом числе итераций). Такая опция доступна пользователям openAI за небольшую плату ($0.5-1 в моих примерах).
В этой статье я покажу как можно обучить GPT-3 (в версии davinchi-003) на своей картине мира и засунуть её внутрь телеграм-бота, потратив на всё всего несколько долларов.
Код бота доступен в репозитарии.
Если вы захотите повторить эксперименты из этой статьи, то нужно будет обзавестись доступом к API OpenAI. Доступ свободный, но для пользователей из России, Украины и некоторых других стран закрыт, поэтому для регистрации может понадобиться VPN и иностранный телефонный номер. После регистрации вы получите $18 для экспериментов. Этого хватит на десяток тренировок и сотню диалогов.
Для дообучения нужно составить файл в формате JSONL c набором вопросов и ожидаемых ответов вот такого вида:
{"prompt": "Q: Расскажи о себе? ->", "completion": " Меня зовут XXX, я программист, живу в Москве. Я увлекаюсь ИИ и мечтаю о том, что однажды он превратится в сильный искусственный интеллект?###"}
{"prompt": "Q: Какие твои любимые фильмы?", "completion": " Мой любимый фильм - Контакт. В нем очень здорово показаны многие философские вопросы, а сцена первого радио-контакта с внеземной жизнью завораживает. Ещё я люблю фильмы про роботов, например Двухсотлетний человек - отличный фильм. Также мне нравится серия Назад в будущее, но это уже из детства. Нестареющая классика.###"}
{"prompt": "Q: Что для тебя важнее - дружба или истина? ->", "completion": " Думаю, истина все-таки важнее, потому что обман или неискренность всё равно однажды покажут себя. Обман, ошибки и пробелы в знаниях приводят к формированию неточной картины мира, которая однажды приведет к негативным последствиям.###"}
Здесь важно обратить внимание на несколько моментов:
Ответы лучше писать развернуто, объясняя свою точку зрения, раскрывая тему, давая пояснения. Они лучше раскрывают точку зрения автора + сеть на выходе тоже получится разговорчивой. Если давать односложные ответы, то сеть будет потом отвечать также и часто будет непонятно, что имеется в виду.
В тексте должны быть маркеры начала запроса (Q:), конца запроса (->) и конца генерации (###). Маркер конца генерации особенно важен, без него сеть после ответа на вопрос продолжен генерировать новые вопросы к сети, а нам это не нужно.
Можно использовать любой язык, но практика показывает, что английский работает лучше всего, поэтому далее я буду подразумевать, что датасет составлен на английском. Переводчик же встроим на самом последнем этапе.
Дальше идёт рутина - нужно написать хотя бы 100 ответов обо всём на свете. А лучше 200. А ещё лучше 1000. Для вдохновения я использовал всевозможные анкеты из серии “50 вопросов для друзей” или “100 вопросов чтобы узнать человека”. Вот один из хороших примеров анкеты на 200 вопросов. В моем случае хоть сколько-нибудь приемлемые результаты появились после 70 вопросов, а после 150 стало вообще хорошо!
Важный вопрос - как проверить качество обучения? Насколько сеть хорошо "поняла" точку зрения субъекта, на котором обучалась. Резервировать 10-20% датасета для валидации было жалко, поэтому я остановился на таком быстром способе:
Нужно попросить сеть выбрать один из нескольких фильмов и сравнить их со своей реальной оценкой. Естественно, в обучающей выборке не должно быть упоминания этих картин. (Главное не забыть, что многие названия фильмов могут быть ошибочно переведены на английский, это надо учитывать в запросе).
Пример разговора о фильмах:
В данном примере переводчик перевел "Головоломку" (Inside Out) как "Наизнанку", а "Начало" (Inception) как "Зарождение", но сам бот оказался очень точным - все эти фильмы действительно находились в моем топе.
Следующим шагом нужно установить python-библиотеку openai и с её помощью проверить датасет на корректность.
openai tools fine_tunes.prepare_data -f dataset.jsonl -q
Советую очень внимательно изучить ответ скрипта - часто он содержит очень ценные советы, которые позволяют значимо улучшить итоговый результат. Если у скрипта нет замечаний к датасету, то можно запускать обучение! (Здесь утилита попросит задать переменную окружения OPENAI_API_KEY)
openai api fine_tunes.create -t dataset.jsonl -m davinci --suffix "<YOUR_MODEL_NAME>"
Обычно оно занимает не более 10 минут, но всё зависит от очереди желающих. Бывает, что процесс растягивается на часы. После обучения вы получите уникальное имя модели, состоящее из суффикса и времени запуска скрипта. Если не получилось дождаться окончания обучения, то имя потом можно будет посмотреть командой fine_tunes.list.
После обучения вы получите модель с которой уже можно общаться в Playground. Вот так это выглядит. Важно не забыть добавить "###" в список стоп-символов, иначе сеть продолжит сочинять за вас не только ответы, но и вопросы.
Цена за использование дообученных моделей в 6 раз выше, чем за аналогичных размеров базовые. Примерно 0.03 цента за 1000 символов прочитанного или напечатанного текста.
Что ж, у нас получился бот, с которым можно обсудить самые насущные вопросы, но он английский и не поддерживает диалогов, поэтому общаться с ним неудобно, так что сделаем простенького тг-бота на Python, который решал бы сразу все эти проблемы.
Алгоритм работы бота следующий:
Каждая входящая фраза переводится на английский с помощью пакета googletrans
Текст оборачивается в промпт (Q: <ЗАПРОС> ->) и отправляется в OpenAI
Результат проверяется на минимальную корректность, переводится на русский и возвращается пользователю.
Также хотелось бы хранить контекст диалога. Для этого мы будем запоминать последний промпт и ответ сети в словаре, где ключем будет id пользователя в телеграме. Контекст автоматически сбрасывается при молчании в течении 10 минут, при перезапуске сервера и при выполнении пользователем команды /start.
Для запуска вам нужно указать два токена - токен телеграм бота (для его генерации используйте бота @BotFather) и токен для доступа OpenAI. Также нужно прописать имя вашей модели и можно запускаться:
python tg_bot.py
На этом всё! Надеюсь, что было интересно! Всем мира и скорейшего наступления сингулярности!
Комментарии (16)
Exchan-ge
25.01.2023 02:59+1но сам бот оказался очень точным
Похоже на то, что он умеет быстро гуглить :)
smartchoice_russia
25.01.2023 08:29+1А возможно его настроить на «пожизненное» обучение? Чтобы все дальнейшие запросы и ответы chatgpt передавались также в файлик и использовались для дообучения вашей цифровой копии?)
smart_pic
25.01.2023 09:25+2А если задать такую фразу "косой косой косил косой косой" - что это значит? Поймет?
заяц инвалид по зрению работал неисправным инструментом :)
Tarakanator
25.01.2023 12:56Такую даже я не понял. Прилагательное к косе не идентифицировал.
Exchan-ge
25.01.2023 14:59Такую даже я не понял. Прилагательное к косе не идентифицировал.
косой — субъект с дефектом зрения
косой — инструмент
косил — действие
косой — дефект инструмента или его специфическая конструкция
косой — название инструмента имеющего дефект или специфическую конструкцию.
(я давно столкнулся с явлением, когда люди не могут пройти капчу — иногда и массово, если не повезет :)Tarakanator
25.01.2023 15:04С разъяснениями-то понятно, я про оригинальную фразу. Кстати вашу интерпретацию я даже с расшифровкой не понимаю.
smart_pic
25.01.2023 15:57+1косой — субъект с дефектом зрения или еще может быть " субъект под действием алкоголя"
косой — субъект, в нашем случае заяц
косил — действие
косой — дефект инструмента или его специфическая конструкция
косой — название инструмента имеющего дефект или специфическую конструкцию
Exchan-ge
25.01.2023 16:41косой — субъект, в нашем случае заяц
Это сугубо локальный мем :)
Для тех, кто никогда не слышал «А нам все равно» — лишено всякого смысла :)
(а для тех, кто таки смотрел «Джентльменов удачи» — появится еще один :)
Так что не будем усложнять задачу для ИИ :)
ksotar
27.01.2023 09:23За GPT-3 не уверен, а вот ChatGPT имеет шансы.
– Переведи на английский фразу "косил косой косой косой", и приведи на русском два подробных возможных варианта её смысла.
– "He was cutting with a crooked crooked crooked scythe."
He was cutting grass with a scythe that was not only bent and twisted, but also had a crooked handle and blade, making the task much more difficult.
He was cutting grass with a scythe that was not only bent and twisted, but also had a crooked handle and blade, while he himself had a physical disability or injury making it hard for him to use the tool in a straight way, and as a result the cutting was not precise and efficient.
– На русском, пожалуйста.
– "Он косил косой косой косой"
Он косил траву косой, которая не только была искривленной и скрученной, но также имела искривленное рукоять и лезвие, что делало задачу гораздо сложнее.
Он косил траву косой, которая не только была искривленной и скрученной, но также имела искривленное рукоять и лезвие, в то время как у него самого была физическая недостаточность или травма, из-за которой ему было трудно использовать инструмент прямо, и в результате коса была неточной и неэффективной.
Exchan-ge
27.01.2023 12:05На русском, пожалуйста.
Таки да, с «Бриллиантовой рукой» и «Джентльменами удачи» его не ознакомили :)
Косой — заяц, «Косой» — кличка.
sergei23090
25.01.2023 17:10При выполнении команды openai tools fine_tunes.prepare_data -f dataset.jsonl -q вылетают ошибки с ссылками на библиотеки
C:\bot\TelegramChatGPT-main>openai tools fine_tunes.prepare_data -f dataset.jsonl -q
Analyzing...
Traceback (most recent call last):
File "C:\Users\Сергей Сергеев\AppData\Local\Programs\Python\Python311\Lib\site-packages\openai\validators.py", line 512, in read_any_format
df = pd.read_json(fname, lines=True, dtype=str)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Сергей Сергеев\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\util_decorators.py", line 211, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Сергей Сергеев\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\util_decorators.py", line 331, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Сергей Сергеев\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\io\json_json.py", line 757, in read_json
return json_reader.read()
^^^^^^^^^^^^^^^^^^
dTi
25.01.2023 20:58Небольшой оффтоп, но вдруг кто-то пользуется API для дописывания текстов: даже при крошечных платных запросах на модель text-davinchi-003 в ответе в 90% случаев возвращается ошибка 503 service overloaded, пользователи в разделе поддержки жалуются на это повально. Модели младше вроде -002 или другие выдают слабый текст. Есть какие-то рабочие и годные аналоги генераторов текста по фразе? Видели много, но все либо очень медленные, либо качество не огонь.
Glamych
27.01.2023 12:11Вопрос из анкеты "Каким был твой самый неподходящий или неловкий пердёж?"
Высокоинтеллектуальный собеседник будет.
turboslon
openai
CLI позволяет также передавать датасет для валидациию Учитывая, что "время - деньги", по результатам валидации можно прикинуть, когда модель "сошлась" и уменьшить количество эпох обучения.После завершения обучения в "обучении" появится прикрепленный файл:
Если этот файл скачать (через CLI я не увидел способа, качаю python-скриптом), то в нем будет видно, как с ростом числа примеров (возможно) улучшаются показатели validation_loss, validation_sequence_accuracy, validation_token_accuracy. Если они делают это (условно) в середине файла, то можно подумать о сокращении количества эпох обучения