Думаю, все уже наслышаны о потрясающих возможностях 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
На этом всё! Надеюсь, что было интересно! Всем мира и скорейшего наступления сингулярности!
openai
CLI позволяет также передавать датасет для валидациию Учитывая, что "время - деньги", по результатам валидации можно прикинуть, когда модель "сошлась" и уменьшить количество эпох обучения.После завершения обучения в "обучении" появится прикрепленный файл:
Если этот файл скачать (через CLI я не увидел способа, качаю python-скриптом), то в нем будет видно, как с ростом числа примеров (возможно) улучшаются показатели validation_loss, validation_sequence_accuracy, validation_token_accuracy. Если они делают это (условно) в середине файла, то можно подумать о сокращении количества эпох обучения
Похоже на то, что он умеет быстро гуглить :)
А возможно его настроить на «пожизненное» обучение? Чтобы все дальнейшие запросы и ответы chatgpt передавались также в файлик и использовались для дообучения вашей цифровой копии?)
Да, никаких проблем с этим нет.
А если задать такую фразу "косой косой косил косой косой" - что это значит? Поймет?
заяц инвалид по зрению работал неисправным инструментом :)
Такую даже я не понял. Прилагательное к косе не идентифицировал.
косой — субъект с дефектом зрения
косой — инструмент
косил — действие
косой — дефект инструмента или его специфическая конструкция
косой — название инструмента имеющего дефект или специфическую конструкцию.
(я давно столкнулся с явлением, когда люди не могут пройти капчу — иногда и массово, если не повезет :)
С разъяснениями-то понятно, я про оригинальную фразу. Кстати вашу интерпретацию я даже с расшифровкой не понимаю.
косой — субъект с дефектом зрения или еще может быть " субъект под действием алкоголя"
косой — субъект, в нашем случае заяц
косил — действие
косой — дефект инструмента или его специфическая конструкция
косой — название инструмента имеющего дефект или специфическую конструкцию
Это сугубо локальный мем :)
Для тех, кто никогда не слышал «А нам все равно» — лишено всякого смысла :)
(а для тех, кто таки смотрел «Джентльменов удачи» — появится еще один :)
Так что не будем усложнять задачу для ИИ :)
За 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.
– На русском, пожалуйста.
– "Он косил косой косой косой"
Он косил траву косой, которая не только была искривленной и скрученной, но также имела искривленное рукоять и лезвие, что делало задачу гораздо сложнее.
Он косил траву косой, которая не только была искривленной и скрученной, но также имела искривленное рукоять и лезвие, в то время как у него самого была физическая недостаточность или травма, из-за которой ему было трудно использовать инструмент прямо, и в результате коса была неточной и неэффективной.
Таки да, с «Бриллиантовой рукой» и «Джентльменами удачи» его не ознакомили :)
Косой — заяц, «Косой» — кличка.
При выполнении команды 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()
^^^^^^^^^^^^^^^^^^
Небольшой оффтоп, но вдруг кто-то пользуется API для дописывания текстов: даже при крошечных платных запросах на модель text-davinchi-003 в ответе в 90% случаев возвращается ошибка 503 service overloaded, пользователи в разделе поддержки жалуются на это повально. Модели младше вроде -002 или другие выдают слабый текст. Есть какие-то рабочие и годные аналоги генераторов текста по фразе? Видели много, но все либо очень медленные, либо качество не огонь.
Сеошные тексты Аль так вообщем?
Вопрос из анкеты "Каким был твой самый неподходящий или неловкий пердёж?"
Высокоинтеллектуальный собеседник будет.