Как я сэкономил $2585 на переводе инди-игры

Вы, конечно, уже догадались что речь пойдёт про втирание ChatGPT дважды в день. Но дьявол, как известно, прячется в деталях, так что описываю весь процесс и цифры. Лонг.

Бабуси всего мира радуются переводу игры на русский. Ййеее
Бабуси всего мира радуются переводу игры на русский. Ййеее

Исходная задача

У меня есть древняя браузерная игра Witchcraft, в которую ещё ваша бабушка играла. А возможно и до сих по играет, и даже иногда заносит кусочек дедовой заначки. В игру каждый день заходит несколько сотен человек, большая часть из них старше 50.

Глядя на новости про то, что российский геймдев отстаёт от общемирового на 15 лет, я решил что моя 13-летняя игра имеет потенциал для успеха в известных соцсетях - она ведь как раз идёт в ногу с локальным временем! А значит, её надо непременно перевести на русский.

Что примечательно, Witchcraft мы уже как-то однажды пробовали запустить в Однодачниках, но это было 7 или 8 лет назад. На тот момент она, очевидно, слишком опережала время и не возымела успеха. Версию под ОК мы в итоге закрыли а русский перевод выпилили за ненадобностью.

Сегодня рунет наконец догнал игру, поэтому я залез в историю версий кода и выкопал там наши старые переводы. Но они, конечно же, частично устарели, а частично не существовали.

Что переводим

Тексты в игре представляют собой табличку ключ-значение, где ключ это место и роль текста в игре, а значение - это кусок текста на английском.

Как я сэкономил $2585 на переводе инди-игры

Оказалось что надо перевести:

Пакет 1 - Тексты в UI

  • 1760 строк (из почти 7000 имеющихся в игре)
  • 47 страниц А4
  • 9690 слов
  • 50600 символов без пробелов (58200 с пробелами)

Пакет 2 - Игровая Wiki

  • 916 блоков текста
  • 50 страниц А4
  • 28500 слов
  • 140950 символов без пробелов (167600 с пробелами)

Солидный объём, как по мне.

Ручной перевод

Я всё аккуратно сложил в гугл-таблицу и пошёл в народ спрашивать, сколько будет стоить перевести такую пачку текстов.

Предложений масса, но их можно разделить примерно на три категории:

  • частные переводчики и маленькие агентства - от $0.07 до $0.15 за слово
  • сервисы переводов (Nitro, Onesky и подобные) - от $0.09 до $0.20 за слово
  • крупные агентства - сказали что назовут цифру после созвона (читай - сдерут сколько смогут), а я такое не выношу

В итоге, перевод моих текстов обошёлся бы мне:

  • Тексты для UI - от $678 до $1647
  • Игровая Wiki - от $1995 до $4845

Итого - от $2670 до $6500. Округлил цифры для наглядности, не бейте.

У меня есть тайный список приятных способов потратить несколько тысяч долларов - и оплата услуг переводчиков в этот список пока не входит. Я решил, что передо мной отличный повод для эксперимента и наконец можно поиграться с API ChatGPT под благовидным предлогом.

Инструментарий

Чтобы перевести текст через ChatGPT, нужно робота вежливо попросить сделать перевод, сообщить контекст и задать правила. Делать это лучше всего автоматически, через API, не через веб-интерфейс, иначе можно быстро кончиться.

Для работы с API я подключил к гугл-таблице вот это расширение. Есть и другие подобные, гугл в помощь.

Скриншот не мой. Но красивый.
Скриншот не мой. Но красивый.

Расширение может работать двумя путями - используя предоставленный вами ключ API или через их собственные ключи. Первый вариант заметно дешевле. Им я и решил воспользоваться, но где-то накосячил при стартовой настройке аккаунта в OpenAI и какое-то время ключ не работал и я платил в три раза дороже.

Когда ключ у меня нормально подключился - стоимость использования расширения примерно сравнялась со стоимостью использования API, то есть в итоге выходит грубо говоря цена работы API × 2. Единственный минус - то что расширение надо оплачивать пакетами по $40, которые надо ещё потрудиться потратить.

Промпты

Для перевода я использовал набор из нескольких промптов, которые комбинировались в единый промпт для функции GPT_TRANSLATE в зависимости от того, какой текст нужно переводить.

Пропт 1 - Специфика перевода

This text is single line of UI text in mobile game. Translation should preserve meaning of original text and should be close to original text in terms of text length. Output translation only, no additional comments. Don't add any html markup, quotation marks, or brackets which are not represented in original text.

Промпт 2 - Разметка HTML

Preserve HTML markup in result translation correspondingly to its use in original text.

Промпт 3 - Ключи для вставки значений в коде

Keep interpolation keys marked with percentage mark followed by key in curly brackets in their proper places within text. Interpolation key syntax should should remain same.

Промпт 4 - Глоссарий (это важно, про него будет ниже)

Use provided glossary to translate game-specific terms. Glossary is list of pairs separated with |, each pair consists of two terms separated by :, first element is term in original language and second element is translation or meaning of this term used in target language. You can adjust pluralization, declension and conjugation of glossary translations to provide best translation results. Glossary: ...

В результате для каждой строчки мы имеем один длинный промпт, составленный из комбинации нескольких. Промпт 1 использовался при переводе каждой строки, промпты 2 и 3 добавлялись если в тексте встречаются символы html-разметки или ключи формата %{key} которые в коде заменяются на цифры или названия. Промпт 4 - когда в тексте встречались слова из глоссария.

Grammar Nazi, конечно, уже пишут комментарии что я безграмотный ибо в промптах отсутствуют артикли "a", "the" и некоторые другие куски английской грамматики. Но дело в том, что при обращениях к API ты платишь за токены (кусочки текста). Артикли в промптах радуют педантов и кассовый аппарат OpenAI, но на выхлоп нейронки не влияют вообще никак. Поэтому я сознательно повырезал всё не несущее смысл.

Глоссарий

Отдельного внимания заслуживает составление глоссария. Это словарик терминов, используемых в игре, и соответствующий им перевод этих терминов.

Глоссарий важно составить и использовать, чтобы часто употребляемые слова и выражения в игре переводились единообразно. Если не использовать глоссарий - одни и те же термины могут быть переведены по разному в зависимости от контекста, и этим в равной степени грешат и роботы, и переводчики-люди.

К примеру, в англоязычной версии моей игры используется слово Coven для обозначения команды игроков. На русский язык оно переводится как "шабаш", что верно с точки зрения контекста, но в играх на русском языке это слово встречается крайне редко. Гораздо более часто употребляемое и понятное слово - "клан". Именно так я и хочу чтобы термин переводился - "coven" везде превращается в "клан", "coven members" в "члены клана", "coven monsters" в "клановые монстры" и так далее. В другом языке это может быть не клан, а какой-нибудь "der Horde" или "共产党".

Для составления глоссария я точно так же использовал ChatGPT - разбил весь текст в кучки по 100 строк, для каждой кучки попросил выделить список терминов, затем отфильтровал и причесал эти термины и тем же ChatGPT их перевёл. Получилось 210 терминов.

Модели

Девчата одобряют мой выбор темы для заметки
Девчата одобряют мой выбор темы для заметки

Для перевода UI я применял модели ChatGPT 3.5 и 4-turbo. Использовал и ту и другую, чтобы посмотреть качество перевода. Модель 4-turbo почти ни разу не выдала результат, который был бы лучше модели 3.5, поэтому я оставил переводы от неё.

Wiki я переводил несколько позже, когда уже вышла модель 4o, и решил опробовать новинку. Смена модели делается в формулах в один клик, а цена использования новой модели оказалась почти такой же как у 3.5

Используемое мной расширение поддерживает и несколько других моделей помимо ChatGPT, но я не стал с ними копаться. Поиски идеала - удел поэтов.

Перевод

Как только промпты и глоссарий были готовы, я засунул их в формулу и радостно растянул её на весь документ. Но нихрена не вышло.

Как оказалось, когда ты только начинаешь пользоваться API, у тебя есть ограничение - не больше 30000 токенов в минуту. Для моих текстов при работе с глоссарием выходило примерно 2-3 тысячи токенов на каждую строку перевода, то есть я мог раз в минуту переводить по 10-15 строк.

Поначалу это было не очень чувствительно, так как я непрерывно допиливал промпты, менял формулу и дорабатывал табличку там и сям. Но когда всё более-менее устаканилось - стало душновато от рутины.

Я потратил примерно 3 часа на то чтобы перевести все тексты из wiki. Ограничение на количество токенов можно повысить, если занести разом $50 на депозит API. Но я, во-первых, не уверен что мне этот депозит понадобится в ближайшее время, а во-вторых, догадался что так можно сделать только когда начал писать эту заметку.

Ещё есть нюанс, что готовый перевод надо из ячейки с формулой обязательно скопировать в новую ячейку и удалить (или отключить) формулу - чтобы она повторно не пересчитывалась при последующих открытиях или когда добавляем/удаляем столбцы и строки. Реально бывает обидно, когда по привычке втыкаешь новый столбец - и несколько сотен формул заново тратят твои деньги. Остановить выполнение уже запущенных формул нельзя.

Первичный результат

Для пакета текстов UI, где использовались модели 3.5 и 4-turbo, получилась примерно следующая статистика:

  • около 60% текстов отлично перевелись без всякого контекста и не потребовали никаких правок
  • 20% текста перевелись лучше если используется глоссарий (я пробовал с ним и без) и итоговый перевод с глоссарием я принял без правок
  • 20% строк после перевода потребовали ручной правки

Стоит оговориться, что две трети исправленных строк - это названия фэнтезийных предметов, монстров и локаций. То есть всё то, что никак не могло попасть в глоссарий, и в целом является скорее вкусовщиной.

Было достаточно много правок для поддержания единообразия переводов, когда, например, монстр называется "Ледяной гигант" а предмет перевелся как "Сапоги ледяного великана", или предметы из коллекции "Стражник" называются "Сапоги стражника" и "Броня охранника".

Были, конечно, и всякие перлы, например "Royal Guardian Shield" робот перевел как "Королевский стражничий щит", а "Viking Ship" как "Викингский корабль". Очевидно, в датасет для обучения входили сочинения пятиклассников.

С пакетом текстов Wiki модель 4o справилась заметно лучше - я поправил чуть меньше 5% текстов. Большинство правок также касалось единообразия переводов терминов, не включенных в глоссарий (название компании в terms of service, например), а также названий игровых предметов и сущностей.

Думаю, на качество перевода Wiki сильно повлияло то, что здесь каждый кусок текста представляет из себя законченную смысловую единицу - заголовок страницы или параграф текста. Для UI многие тексты не имеют очевидного контекста и их можно перевести по-разному в зависимости от места использования. К примеру, одно и то же слово "View" можно перевести как "Просмотр" если это заголовок диалога и как "Посмотреть" если это надпись на кнопке.

Валидация

Все переведенные тексты я самолично прочитал. Может, где-то не очень дотошно, но как минимум пробежал глазами и поправил косяки где заметил. Смысловых расхождений между оригиналом и переводом не заметил ни разу.

Помимо ручной вычитки, я проверял все переводы по следующим правилам:

  • совпадение HTML-разметки по маске (убираем текст, оставляем только теги) - здесь робот дал почти стопроцентно правильный результат, а в паре мест даже исправил косяки разметки, которые были в оригинале
  • сохранение ключей интерполяции - тоже почти 100% корректности
  • одинаковость числовых значений в исходнике и переводе - тут 100%
  • если текст в переводе становится значительно длиннее или короче - это требовало корректировки или как минимум проверки
  • совпадение пунктуации - здесь было несколько ошибок, например могло потеряться двоеточие или вместо восклицательного предложения предложение с точкой

Для всех этих проверок я сделал просто столбцы в документе, по которым фильтровал записи и вручную всё проверял. У меня в документ были внесены все строки игры, не только те которые надо было перевести, поэтому я ещё до кучи и несколько косяков в старых переводах поправил.

Колонки с валидацией, прям как у роботов
Колонки с валидацией, прям как у роботов

При переводе wiki был интересный момент. В некоторых параграфах используются вставки кода на ruby и в этом коде в виде параметров функций попадаются строки, которые нужно переводить. Эти строки никак не отличаются от других таких же строк в том же куске кода, которые переводить не надо. Я не давал никаких инструкций касательно этого кода и планировал его сам переводить, но в итоге оказалось что робот успешно перевел нужные строки в более чем сотне случаев использования и накосячил всего один раз.

Деньги и время

На первичные эксперименты по работе с API и перевод пакета UI у меня ушло примерно $45. Это было до того, как я корректно настроил ключи. С нормально настроенными ключами я тот же объём текста перевел уже за $15.

На перевод Wiki с ключами и уже классно настроенной гугл-таблицей ушло ещё примерно $25.

На настройку таблички, сам перевод, вычитку и исправление косяков перевода у меня ушло суммарно около 10-15 рабочих часов. Если бы я занимался только вычиткой и правкой - ушло бы часа 4-5.

Итого потрачено: $85.
Вместо $2670 (как минимум).

Стоит учесть, что я переводил с языка, который хорошо знаю, на свой родной язык, а значит мог сам заниматься вычиткой и мне не пришлось за это платить (деньгами). Однако, если количество времени, потраченное на вычитку, умножить на примерную ставку переводчика в час, то выйдет не шибко много, не больше пары сотен.

Что можно улучшить

Для следующих переводов, уже на незнакомые мне языки, я хочу:

1) Использовать глоссарий не целиком, а частично. Сейчас если в строке встречается одно слово из глоссария - он идёт в промпт целиком, что раздувает количество токенов в запросе и сжирает лимиты. Теоретически, будет достаточно включать 2-3 пары слов из глоссария для получения того же самого результата.

2) Более детально разметить тексты в соответствии с их использованием в игре. Если речь идёт о кнопке, заголовке или названии предмета - это нужно указывать в промпте, чтобы робот корректировал перевод соответственно.-

3) Сгруппировать куски текста по смыслу и давать их в качестве контекста перевода. К примеру, если предметы из одной коллекции - сообщать название коллекции и то как оно было переведено. А если кнопка показывается внутри диалога покупки - давать в промпте лежащий рядом текст с описанием промо-акции.-

4) Добавить какую-то автоматизацию вызова функций перевода и копирования результатов. Сейчас это приходится делать вручную по 10-15 строк в минуту и это капец как нудно.

5) Ну и, конечно же, вычитку лучше доверить профессиональному переводчику или, как минимум, носителю языка.

Выводы

По моему мнению, переводы через LLM уже вполне можно делать и, по крайней мере, для одного языка результат будет очень хороший. 95% текстов игровой Wiki и 85% текстов для UI и внутриигровых названий робот перевёл практически идеально и я уверен, что это не предел.

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

Полноценный перевод нарративной составляющей игр и художественных произведений через ChatGPT пока ещё скорее утопия. Но для рутинного перевода UI, документации, инструкций, wiki и других кусков текста, не обременённых художественной составляющей - уже реальность.

Если вам понравилась статья - ставьте лайки, пишите комментарии, подписывайтесь на меня на DTF или пишите мне в телеграм.

Спасибо за внимание!

113113
34 комментария

В общем и целом очень познавательно, спасибо. Постоянно думаю о том как применить GPT в рабочих задачах и жизни, впервые узнал про плагин к гугл таблицам, это прям расширяет горизонты

4
Ответить

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

Так и здесь — нафига натягивать сову на глобус? Чтобы "пацаны во дворе" не засмеяли? Когда появится задача и ты поймёшь, что её можно легче решить с помощью гпт, то бери и пользуйся.

P.S. А может уже поздно и я тебя не так понял, и ты как раз об этом — что при возникновении задачи ты думаешь можно ли её решать через гпт :)

2
Ответить

Жирный лайк ))

3
Ответить

😘

Ответить

Grammar Nazi, конечно, уже пишут комментарии что я безграмотный ибо в промптах отсутствуют артикли "a", "the" и некоторые другие куски английской грамматики. Но дело в том, что при обращениях к API ты платишь за токены (кусочки текста). Артикли в промптах радуют педантов и кассовый аппарат OpenAI, но на выхлоп нейронки не влияют вообще никак. Поэтому я сознательно повырезал всё не несущее смысл.Бог оптимизации, респект!

1
Ответить

Если уж экономить,то экономить на всём!

7
Ответить

Из прочитанного понял не так много, как хотелось бы, но интересно.

2
Ответить