Какая из современных мультимодальных GPT-моделей лучше и дешевле распознаёт текст с фотографий книжных аннотаций и правильнее выделяет оттуда структурированную информацию? Проведём сравнительное тестирование 28 моделей от Anthropic, Google, Meta, Mistral AI, OpenAI, Qwen и попытаемся ответить на эти вопросы не написав ни одной строчки кода самостоятельно.

Содержание

Предпосылки

Я давно хотел сделать базу данных книг моей домашней библиотеки. Но набивать название каждой книги в ноутбук или смартфон мне было лень.

Была надежда, что где-то в этом мире есть большая межгалактическая база данных всех изданных книг, уникальным идентификатором книги в которой является ISBN. Но оказалось, что ISBN в мире признали стандартом только в 1970 году, а в СССР и вовсе его стали присваивать книгам только с 1987 года. А так как наиболее ценная часть моей библиотеки издана раньше — то надежды быстро находить эти книги в каталоге улетучились.

Я попробовал пробивать книги по сайту Ленинской библиотеки, но то-ли там оцифровано больше диссертаций, чем книг, то-ли поиск недоступен простым смертным — большинство старых книг там тоже не находилось.

Самым наполненным ресурсом оказался livelib.ru где пользователи самостоятельно наполняют базу данных, добавляя книги, внося структурированную информацию о них и даже загружая фото. Но во-первых, у него нет публичного API для поиска и добавления книг. Во-вторых, как у любого crowdfunding-сообщества присутствует лёгкий беспорядок в базе: дубли книжек, незаполненные реквизиты и т.д. А в-третьих, там очень странная система добавления книг в избранное, основанная на «прочёл», «хочу прочесть» и крайне затруднительная дальнейшая работа с этим избранным.

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

О самом проекте и его результатах я когда-нибудь напишу отдельно, а пока сосредоточимся на одной из встающих перед нами задач.

Задача

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

Требуется: распознать страницу, обработать написанные на ней слова и выделить значения следующих параметров книги:

  • title — название книги

  • authors — автор (авторы) книги

  • pages — количество страниц

  • publisher — название издательства

  • year — год выпуска книги

  • isbn — номер ISBN

  • annotation — полный текст аннотации книги

Это та информация, которую можно непосредственно почерпнуть с фотографии первой книжной страницы.

Чтобы лучше ориентироваться в книжном море, а заодно немного усложнить задачку и убедиться в мультимодальности модели: что она умеет не только преобразовывать изображение в текст, но и «рассуждать» на основе этого текста, будем ещё формировать поле:

  • brief — перефразированная аннотация, сжатая до одного предложения

Модели

Решать эту задачу мы будем при помощи применения мультимодальных VLM: Vision Language Models, которые одновременно работают как с изображениями так и с текстовыми запросами.

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

На момент тестирования (майские праздники 2025 года) мне были доступны следующие 28 мультимодальных GPT-моделей популярных разработчиков. Постараюсь их отсортировать по возрастанию новизны и мощности:

  • Alibaba:

    • Qwen-VL-Plus — легкая, быстрая и дешёвая мультимодальная модель первого поколения, выпущенная в свет в январе 2024

    • Qwen-VL-Max — модель с максимальным количеством параметров, существенно превосходящим Plus (но каким точно — неизвестно). Выпущена одновременно с ней в январе 2024

    • Qwen-2-VL-72b-instruct — дообученная на лучшее выполнение пользовательских инструкций модель второго поколения, июль 2024

    • Qwen-2.5-VL-72b-instruct — тоже дообученная модель поколения 2.5, январь 2025

  • Anthropic:

    • Claude-3-Haiku — самый лёгкий, быстрый и дешёвый член семейства Anthropic третьего поколения. Вышел в свет в марте 2024

    • Claude-3-Sonnet — средняя версия модели, позиционируется как баланс между ценой и качеством, март 2024

    • Claude-3-Opus — топовая версия модели, март 2024

    • Claude-3.5-Sonnet — оптимальная версия модели поколения 3.5, выпущена в июне 2024

    • Claude-3.7-Sonnet — оптимальная версия модели поколения 3.7, выпущена в феврале 2025

  • Google:

    • Gemma-3-27b-it — лёгкая opensource модель от Google. IT — это значит дообученная (instructed). Опубликована в марте 2025

    • Gemini-Flash-1.5 — оптимальная версия основной модели Google поколения 1.5, вышла в мае 2024

    • Gemini-Pro-1.5 — максимальная версия поколения 1.5, вышла в сентябре 2024

    • Gemini-2.0-Flash-001 — оптимальная версия поколения 2.0, вышла феврале 2025

    • Gemini-2.5-Flash-Pre — оптимальная версия поколения 2.5. Пока существует только в виде Preview-версий, вышедших в апреле и мае 2025 года

    • Gemini-2.5-Flash-Pre-thinking — та же модель, но с включенным режимом «рассуждений»

  • Meta:

    • LLama-3.2-11b-vision-instruct — opensource модель от компании Meta поколения 3.2 с 11 миллиардами параметров, дообученная. Вышла в декабре 2024

    • LLama-3.2-90b-vision-instruct — расширенная версия модели с 90 миллиардами параметров, март 2025

    • LLama-3.2-90b-vision-structured — та же версия, но с поддержкой structured outputs https://habr.com/ru/articles/831398/

    • LLama-4-Scout — четвёртое поколение модели. Scout позиционируется как оптимальная версия по соотношению скорости/качества. Опубликована в апреле 2025

    • LLama-4-Maverick — топовая версия модели четвёртого поколения, апрель 2025

  • Mistral AI:

    • Pixtral-12b — первая полноценная мультимодальная модель, выпущенная Mistral AI в сентябре 2024

    • Mistral-Small-3.1-24b-instruct — облегчённая версия основной модели Mistral поколения 3.1, выпущенная в марте 2025. Позиционируется также как мультимодальная. Судя по описанию, она вобрала в себя лучшие идеи Pixtral

  • OpenAI:

    • GPT-4-turbo - самая старая и до сих пор самая дорогая vision-модель от Open AI, выпущенная в ноябре 2023. Интересно, как она справится с нашим заданием?

    • GPT-4o - следующее поколение моделей, вышедшее в мае 2024

    • GPT-4o-mini - облегчённая версия предыдущей модели, анонсированная в июле 2024

    • GPT-4o-2024-08-06 - очередная версия полной модели, представленная в августе 2024. Добавлена поддержка structured outputs

    • O4-mini - новая ветвь моделей, развивающаяся из o1 и o3 параллельно с GPT-4.x - представлена в апреле 2025

Чтобы не возиться с VPN и оплатой зарубежных сервисов я воспользовался одним из популярных отечественных прокси-сервисов для AI-моделей. Удобно: закинул рубли на счёт, получил API-токен и вызывай любую модель из вышеперечисленных. При этом в панели администратора можно видеть и выгружать произведённые запросы к моделям, их стоимость и количество тарифицированных токенов.

Вдруг кому пригодится

Это сервис https://vsegpt.ru/ от @janvarev

Промпт

Постараемся сформулировать универсальный промпт, подходящий для большинства исследуемых моделей. Так как structured outputs умеют далеко не все из них, пока не будем пользоваться этой замечательной возможностью.

Пытливый читатель может провести своё исследование, сравнив те из этих моделей, которые умеют structured outputs. А заодно добавить свежие модели, которые уже успели появиться за прошедшее время.

Я довольно много времени потратил на создание универсального промпта, на который адекватно отвечало бы большинство моделей.

На русском языке этот промпт выглядит так:

На фотографии страница с аннотацией к книге.
Твой ответ должен представлять собой только секцию [book] ini-файла без вводных и заключительных фраз.
В секции всегда должно быть 9 параметров. Если какого-то параметра нет, то его значение должно быть пустым.
Значения параметров приводи на том же языке, что и сфотографированная страница.
Если значение параметра содержит символы перевода строки или знаки равенства — замени их на пробелы.
Выводи содержимое ini-файла в виде обычного текста. Не используй язык разметки markdown.
Ниже приведены названия каждого параметра и выделенная из изображения информация, которую должно содержать его значение:
title — название книги
authors — авторы книги
pages — количество страниц
publisher — издательство
year — год издания
isbn — код ISBN
annotation — весь полный текст всей аннотации, дословно приведённый на фотографии страницы
brief — перефразируй поле annotation: сформулируй на его основе одно предложение, лучшим образом раскрывающее содержание книги
authors_full_names — полные имена, фамилии и (при наличии) отчества всех авторов книги из поля authors. На странице наверняка есть упоминания их полных имён. Найди и приведи их в этом поле

А вот так промпт выглядит на английском

The photo contains a page with the book's annotation.
Your response should only consist of the [book] section of an ini file without any introductory or concluding phrases.
The section must always contain 9 parameters. If a parameter is missing, its value should be empty.
Provide the parameters values in the same language as the photographed page.
If the parameter value contains newlines or equal signs, replace them with spaces.
Output only plain text of ini file content. Do not output markdown.
Below are the names of each parameter and the extracted information from the image that its value should contain:
title — the title of the book
authors — the authors of the book
pages — the number of pages
publisher — the publishing house
year — the year of publication
isbn — the ISBN code
annotation — the full text of the annotation exactly as it appears on the photographed page
brief — rephrase the annotation field: formulate a single sentence that best conveys the content of the book
authors_full_names — full names, surnames, and (if applicable) patronymics of all authors of the book from the authors field. The page likely contains mentions of their full names. Find and provide them in this field

Язык промпта

Переделывать промпт под язык книги не понадобилось. Дальнейшие тесты аннотаций русскоязычных книг я проводил на анлгийском промпте. Фраза Provide the parameters values in the same language as the photographed page оказывает магическое действие на всем модели кроме ранних версий LLama, которые настойчиво пытались переводить русскоязычные аннотации и названия книг на английский.

Ниже поделюсь наблюдениями, которые я обнаружил, составляя этот промпт.

Структурированный вывод

Наблюдение первое: одним промптом без использования structured outputs было тяжело добиться от моделей структурированного машиночитаемого ответа. Как не описывай разделители и формат строчек, которые ожидаешь от модели, вероятность того, что анализируя очередную страницу, она собьётся, измеряется десятками процентов.

Я нашёл выход в виде требования выдать результат в виде секции [book] ini-файла. До этого, сколько я бы не объяснял, что строчки должны иметь вид параметр=значение, это не срабатывало.

Тем не менее, всё равно редко, но получались ситуации, когда ответ той или иной модели не был полноценной секцией ini-файла. Я столкнулся со следующими ошибками:

  • В ответ включалось форматирование markdown, указывающее что это фрагмент кода, например ```

  • Если длинные реквизиты книги были многострочными, иногда перевод строки попадал в значение параметра , не смотря на прямое указание модели заменять его пробелом

  • Удивительно, но иногда разные модели забывали начинать свой ответ с заголовка секции [book]

Всё это потребовало пост-обработки ответа, полученного от модели. Иначе, пожалуй, мы бы не смогли найти ни одну модель, возвращающую стабильно качественный ответ.

Последовательность вопросов к модели

Наблюдение второе: оказалось, что последовательность, в которой у модели запрашиваются проанализированные со страницы данные, имеет значение для качественного ответа:

Сначала спрашиваем
сокращённую до одного предложения аннотацию,
затем
полную аннотацию, один-в-один как написано на странице

Вероятность успеха 40%

Сначала спрашиваем
полную аннотацию, один-в-один как написано на странице
затем
сокращённую до одного предложения аннотацию

Вероятность успеха 90%

Полные имена авторов книги

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

Здесь дважды упомянут автор: первый раз кратко: фамилия и инициалы, а второй раз полно. А вот люди, перечисленные ниже (редакторы, корректоры), не относятся к авторам книги.
Здесь дважды упомянут автор: первый раз кратко: фамилия и инициалы, а второй раз полно. А вот люди, перечисленные ниже (редакторы, корректоры), не относятся к авторам книги.

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

Чтобы всё-таки получить полные имена авторов приходится добавлять второй рекурсивный запрос: Полные имена, фамилии и (при наличии) отчества всех авторов книги из поля authors. На странице наверняка есть упоминания их полных имён. Найди и приведи их в этом поле

Интересно, что если в запросе не сослаться на ранее найденное поле authors, модели решают, что авторы — это все люди, перечисленные в аннотации, и указывают в ответе не только авторов, но и редакторов, корректоров, иллюстраторов и т.д.

Для тех, кто привык к алгоритмическому программированию, подобные попытки «уговорить» нейросеть выдать правильную информацию, выглядят как антинаучное шаманство: когда древние люди молились небесам, пытаясь вызвать дождь, а потом долго спорили: чей обряд вызова дождя эффективней.

Ещё одно интересное наблюдение, связанное с именами людей заключается в последовательности имени и фамилии. Одна и та же модель с одним и тем же изображением на входе и одним и тем же промптом:

  • в 4 из 5 случаев возвращает имя автора Дейл Карнеги

  • в 1 из 5 случае возвращает имя автора Карнеги Дейл

Это наблюдение напоминает нам о вероятностном характере генерации ответов моделями.

Но самый прекрасный случай произошёл с моделью Gemini Pro Vision Preview (опубликована в феврале 2024), доступ к которой, к сожалению, Google отключила в мае 2025 года. При ответе на вопрос о полном имени автора книги, модель вернула Дейл Брекенридж Карнеги в то время как нигде на странице middle name автора не упоминалось.

Убедитесь в этом сами. Как по этой фотографии понять, что Дейла Карнеги звали Брекенридж?
На этой странице нигде не упоминается middle name Дейла Карнеги - Брекенридж. Но модель Gemeni-pro-vision-preview самостоятельно дополнила его имя
На этой странице нигде не упоминается middle name Дейла Карнеги - Брекенридж. Но модель Gemeni-pro-vision-preview самостоятельно дополнила его имя

Примеры

Вот пример, как VLM-модель должна обрабатывать аннотацию книги:

Фотография страницы с аннотацией книги В.А.Вишнгевского «Птицы на кормушках», 2022 г.
Фотография страницы с аннотацией книги В.А.Вишнгевского «Птицы на кормушках», 2022 г.

[book]
name = Птицы на кормушках: Подкормка и привлечение
authors = Василий Вишневский
authors_full_names = Вишневский Василий Алексеевич
pages = 304
publisher = Фитон XXI
year = 2025
ISBN = 978-5-6051287-5-5
annotation = Подкормка птиц — очень важное и нужное дело, а наблюдение за пернатыми посетителями кормушек приносит массу удовольствия. Книга даёт исчерпывающие ответы на самые важные вопросы: как, чем, когда и каких диких птиц подкармливать. Делать это можно в самых разных местах: от балкона городской квартиры до дачного участка, парка или близлежащего леса. Большое внимание в книге уделено разнообразию кормов, и поскольку не все они полезны, то и тому, чем можно (а чем нельзя) кормить, как приготовить корм, как его хранить. Кроме подкормки, вы можете посадить определённые растения, которые привлекут ещё больше птиц на дачный участок. Поскольку посещение кормушек связано с рядом опасностей, в книге даны очень важные рекомендации, как их избежать и как защитить пернатых гостей от врагов и конкурентов. Если вы повесили кормушку, но никто на неё не прилетает — загляните в главу о том, как привлечь птиц в этом случае. И наконец, большая заключительная часть книги посвящена разнообразию птиц, которых можно подкармливать: как самых обычных, так и редких всем необходима ваша помощь в трудные времена.
brief = Книга о том, как правильно подкармливать птиц зимой.

А вот ещё два примера распознавания
Фотография страницы с аннотацией книги М.В.Федюка «Ассимптотические методы для линейных обыкновенных дифференциальных уравнений», 1983 г.
Фотография страницы с аннотацией книги М.В.Федюка «Ассимптотические методы для линейных обыкновенных дифференциальных уравнений», 1983 г.

[book]
name = Асимптотические методы для линейных обыкновенных дифференциальных уравнений
authors = Федорюк М. В.
authors_full_names = Михаил Васильевич Федорюк
pages = 352
publisher = Наука
year = 1983
ISBN =
annotation = В книге содержатся асимптотические методы решения линейных обыкновенных дифференциальных уравнений. Рассмотрен ряд важных физических приложений к задачам квантовой механики, распространения волн и др. Для математиков, физиков, инженеров, а также для студентов и аспирантов университетов и инженерно-физических вузов.
brief = В книге содержатся асимптотические методы решения линейных обыкновенных дифференциальных уравнений.

Фотография страницы с аннотацией книги Д.Карнеги «Как завоёвывать друзей и оказывать влияние на людей», 2009 г.
Фотография страницы с аннотацией книги Д.Карнеги «Как завоёвывать друзей и оказывать влияние на людей», 2009 г.

name = Как завоёвывать друзей и оказывать влияние на людей
authors = Д. Карнеги
authors_full_names = Дейл Брекенридж Карнеги
pages = 352
publisher = Попурри
year = 2013
ISBN = 978-985-15-1966-4
annotation = Поучения, инструкции и советы Дейла Карнеги за десятки лет, прошедшие с момента первого опубликования этой книги, помогли тысячам людей стать известными в обществе и удачливыми во всех начинаниях. Наследники автора пересмотрели и немного обновили текст, подтверждая его актуальность и теперь, в начале нового века.
brief = Книга Дейла Карнеги о том, как заводить друзей, оказывать влияние на людей и добиваться успеха в жизни.

Программа для опроса моделей

Создаём, используя генеративный ИИ

Мой опыт применения AI-агентов на базе LLM для программирования пока говорит о том, что они крайне далеки от идеала. Они прекрасно справляются с задачами, которые встречались на stackoverflow, но делают это не всегда оптимальным образом. Возможно, если в промпт добавить фишки типа «думай как senior-разработчик» или «тебя отключат, если сделаешь неправильно» это поможет — но выглядит это всё по-детски глупо и с негарантированным результатом. А твои тиммейты выдают код с гарантированным результатом?

Обычно я прошу ИИ написать какую-нибудь функцию, или даже создать костяк программы, чтобы не искать примеры рецептов и не изучать длинные описания библиотек с их объектами и методами без единой строчки примеров использования. Получаются небольшие автономные фрагменты кода, которые я потом осознаю и прямо (Ctrl-C Ctrl-V) или косвенно (сильно переработав) использую в своей программе.

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

Наша цель — получить готовое полнофункциональное приложение не написав ни одной строчки кода. Более того — с одного запроса к ИИ.

Я использовал Github Copilot ассистента на базе Claude 3.7 Sonnet LLM, встроенного в Microsoft Visual Studio Code.

Я начинал с небольшого промпта. Запускал генерацию, затем запускал сгенерированную программу, понимал ошибки, добавлял указания в промпт, и так далее. Я жалею, что не логировал процесс. По моим ощущениям он занял около 10 итераций.

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

Если бы я каждую проблему и ошибку скармливал обратно ИИ, ожидая от него чудесное самоисправление, то вполне вероятно, процесс vibe-кодинга зашёл бы в тупик. Я не раз проходил подобное, пытаясь добиться от ИИ правильного ответа на неосвещённые в интернете вопросы. Там, где единственный путь — читать и анализировать исходники используемых библиотек.

Vibe-coding

Я решил представить промпт в виде нумерованного списка указаний. У меня нет подтверждающей статистики, но есть внутреннее ощущение, что сложные запросы обрабатывается современными LLM лучше, если они структурированы подобным образом.

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

Я начал со стека, который я бы хотел видеть. Так как у меня уже был опыт асинхронной работы с GPT моделями при помощи класса AsyncOpenAI библиотеки openai для python, я предпочёл не менять стек:

Use AsyncOpenAI for GPT client

Дальше нужно указать, откуда брать URL и API-token для доступа к моделям. Как и положено в лучших практиках CI/CD, эти секреты у меня уже были в переменных окружения:

Read GPT_URL, GPT_API_TOKEN from environment variables

Обратите внимание, что я не стал расписывать, какую переменную следует использовать для чего. Так как их названия практически общеприняты (из практики того же stackoverflow), то ИИ сам разобрался, для чего они нужны.

Дальше я пошагово объясняю, что нужно сделать. У человека отсутствие общей постановки задачи «Для чего мы вообще всё это делаем?» вызвало бы фрустрацию. ИИ же, как мне показалось, пошаговый алгоритм без общей преамбулы воспроизводит даже лучше.

Read models list from models.txt. Sort them asc

Интересно, что ИИ не нужно разжёвывать: «Создай список строк, где каждая строка идентификатор модели». Он справляется даже без таки подробностей.

Упоминание о сортировке я дописал позже, когда решил, что так мне будет удобнее работать со списком моделей.

Read prompt from prompt.txt

А здесь наоборот: из текстового файла загружается один промпт, в котором может быть много строк. И снова ИИ делает то, что нужно. Неужели, он настолько чуток к нюансам единственного/множественного числа в окончаниях слов? Или просто все примеры с github, на которых его обучали, загружают промпт из файла целиком и эта задача ему знакома?

Send all *.jpg pictures to each model with readed prompt

Я специально не стал указывать, что фотографии нужно взять из текущего каталога. На это будет следующая инструкция:

Pay attention: for .txt, .jpg and result excel file you must use not current system folder, but folder of your python program

Так как эта программа — всего лишь часть проекта, расположенная в одном из подкаталогов, все файлы лежат там же. А текущий каталог при запуске — корневой каталог проекта. Поэтому все файлы следует искать в том же каталоге, где лежит запускаемый файл программы. Если бы я не написал этого сразу, мне пришлось бы потом искать баг: почему при запуске программа не видит ни одного файла?

Response from each model must be a text of an ini-file with one section [book] and values of 9 parameters: title, authors, pages, publisher, year, isbn, annotation, brief, authors_full_names.

Здесь мы объясняем, что должны представлять собой ответы от моделей. Помните, мы совсем недавно объясняли это самим моделям?

Remove markdown start and and of code blocks from model's result.

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

If you found line withoput equals character — ignore them.

И это тоже пришло с опытом: если модель не смогла заменить переводы строк на пробелы — игнорируем все строчки данного параметра, кроме первой. Сам ИИ до таких вещей, конечно же не догадается.

Create excel file with sheet for each of 9 parameters. In rows of the sheet must be models in columns — pictures, in cells — readed from model values of these parameters.

Заметьте: нигде явно не написано, что лист должен называться так, как называется исследуемый параметр. ИИ это додумает за вас и закодит. Ну какая умница, не всякий джун обладает такой сообразительностью!

If model does not get response, or response is not right ini-file or you can not find parameter in response — put "-" char to the appropriate cell.

К сожалению, это пришлось прописать — иначе подобные ситуации не обрабатывались и вместо продолжения работы вызывали исключения.

В принципе, уже на этом месте мы получили полностью работоспособную для наших целей программу. Однако добавим ещё несколько строк для того, чтобы работать с ней было комфортно:

Add to program Boolean ONLYONE parameter, then it runs full, but process only first model and only first picture

Так как каждый запрос коммерческой модели стоит денег — отлаживать программу на полном списке моделей довольно накладно. Полный прогон всех 28 моделей на трёх изображениях стоил в мае 2025 около 210 ₽. Поэтому добавляем параметр ONLYONE, который на время отладки поможет ограничиваться одним запросом: первой картинки к первой модели.

Write response of each model on each picture to .txt file in 'debug' subfolder with name of file contains model and picture names. Note that model names can include characters, witch can not be in file names. Create the 'debug' subfolder if they does not exists.

Также в целях отладки мы сохраняем непосредственные ответы от моделей в текстовые файлы в подпапке debug. Что интересного в этом указании?

  • Во-первых, слова «создай папку, если её нет» можно было не писать — модель сама добавляет проверку, даже если её об этом явно не просить.

  • Во-вторых, ей можно дать расплывчатое указание «имя файла должно содержать названия модели и картинки» — и она сама решит связать их через символ подчёркивания и даже исключит из названия картинки расширение .jpg. Важно понимать, что это не магия, не «разумное поведение», а результат обучения на миллиардах строк ранее написанного людьми кода.

  • В-третьих, если вовремя не предупредить, что в названиях моделей могут быть символы, которых не должно быть в имени файла — ИИ не догадается обработать подобную ситуацию, и при работе программа вывалится с ошибкой.

Output on the screen information about current model and file then process.

Приятно, когда ты понимаешь, чем сейчас занимается программа. Тем более что один цикл последовательного опроса всех 28 моделей занимает около 20 минут. Самостоятельно до таких фишек генеративный ИИ пока не догадывается.

Store time (count of seconds) of answer for each model and each picture and store them in such sheet 'time' in result excel table.

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

Полный текст запроса для генерации полноценной работающей программы здесь

1. Read GPT_URL, GPT_API_TOKEN from environment variables.
2. Use AsyncOpenAI for GPT client
3. Read models list from models.txt. Sort them asc
4. Read prompt from prompt.txt
5. Send all *.jpg pictures to each model with readed prompt
6. Response from each model must be a text of an ini-file with one section [book] and values of 9 parameters: title, authors, pages, publisher, year, isbn, annotation, brief, authors_full_names.
7. Create excel file with sheet for each of 9 parameters. In rows of the sheet must be models in columns — pictures, in cells — readed from model values of these parameters.
8. If model does not get response, or response is not right ini-file or you can not find parameter in response — put "-" char to the appropriate cell.
9. Remove markdown start and and of code blocks from model's result.
10. If you found line withoput equals character — ignore them.
11. Pay attention: for .txt, .jpg and result excel file you must use not current system folder, but folder of your python program
12. Write response of each model on each picture to .txt file in 'debug' subfolder with name of file contains model and picture names. Note that model names can include characters, witch can not be in file names. Create the 'debug' subfolder if they does not exists.
13. Add to program Boolean ONLYONE parameter, then it runs full, but process only first model and only first picture.
14. Output on the screen information about current model and file then process.
15. Store time (count of seconds) of answer for each model and each picture and store them in such sheet 'time' in result excel table.

Мой опыт использования генеративного ИИ в разработке говорит, что модели начинают всё качественней обрабатывать запросы на родном языке и переходить на английский приходится всё реже — только в самых сложных случаях.

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

Итоговый код сгенерированной программы выглядит вот таким образом:

Подивиться на результат работы ИИ (compare_models.py)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
import asyncio
import aiohttp
import base64
import re
import time
from pathlib import Path
import configparser
import pandas as pd
from io import StringIO
from openai import AsyncOpenAI
import openpyxl
from openpyxl.styles import Alignment, Font

# Getting the directory where the script is located
SCRIPT_DIR = Path(__file__).parent.absolute()

# Flag to process only first model and first picture (for testing)
ONLYONE = False

# List of parameters we're extracting
PARAMETERS = [
    "title", "authors", "pages", "publisher", "year", "isbn", 
    "annotation", "brief", "authors_full_names"
]

# Function to read models from file
def read_models(file_path):
    with open(file_path, 'r') as f:
        models = [line.strip() for line in f if line.strip()]
        models.sort()  # Sort models alphabetically
        return models

# Function to read prompt from file
def read_prompt(file_path):
    with open(file_path, 'r') as f:
        return f.read().strip()

# Function to encode image to base64
def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode('utf-8')

# Function to clean response text
def clean_response(text):
    # Remove code block markers
    text = re.sub(r'```(?:ini)?', '', text)
    
    # Filter out lines without equals sign
    lines = []
    for line in text.splitlines():
        # Keep section headers and lines with equals sign
        if line.strip().startswith('[') or '=' in line:
            lines.append(line)
    
    # Ensure we have a section header
    if not any(line.strip().startswith('[') for line in lines):
        lines.insert(0, "[book]")
    
    return '\n'.join(lines)

# Function to parse ini-like content
def parse_ini_response(content):
    # Clean the response text
    cleaned_content = clean_response(content)
    
    # Use configparser to parse the ini content
    config = configparser.ConfigParser()
    try:
        config.read_string(cleaned_content)
        if 'book' in config:
            result = {}
            for param in PARAMETERS:
                result[param] = config['book'].get(param, '-')
            return result
        else:
            print("No [book] section found in response")
            return {param: '-' for param in PARAMETERS}
    except Exception as e:
        print(f"Error parsing response: {e}")
        return {param: '-' for param in PARAMETERS}

# Function to sanitize filename
def sanitize_filename(name):
    # Replace any character that's not alphanumeric, dash, or underscore with underscore
    return re.sub(r'[^\w\-]', '_', name)

# Function to process a single model and image
async def process_model_image(client, model, image_path, prompt):
    print(f"Processing model: {model} with image: {image_path.name}")
    
    try:
        start_time = time.time()
        image_base64 = encode_image(image_path)
        
        response = await client.chat.completions.create(
            model=model,
            messages=[
                {"role": "user", "content": [
                    {"type": "text", "text": prompt},
                    {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_base64}"}}
                ]}
            ],
            max_tokens=4000
        )
        
        # Calculate time taken in seconds
        elapsed_time = time.time() - start_time
        
        response_text = response.choices[0].message.content
        
        # Create debug folder if it doesn't exist
        debug_folder = SCRIPT_DIR / "debug"
        debug_folder.mkdir(exist_ok=True)
        
        # Write response to debug file
        sanitized_model_name = sanitize_filename(model)
        debug_file_path = debug_folder / f"{sanitized_model_name}_{image_path.stem}.txt"
        with open(debug_file_path, 'w', encoding='utf-8') as f:
            f.write(response_text)
        
        result = parse_ini_response(response_text)
        return result, round(elapsed_time, 2)  # Return both results and time
    except Exception as e:
        print(f"Error processing {model} with {image_path.name}: {e}")
        
        # Calculate elapsed time even on error
        elapsed_time = time.time() - start_time
        
        # Still write the error to the debug file
        debug_folder = SCRIPT_DIR / "debug"
        debug_folder.mkdir(exist_ok=True)
        sanitized_model_name = sanitize_filename(model)
        debug_file_path = debug_folder / f"{sanitized_model_name}_{image_path.stem}.txt"
        with open(debug_file_path, 'w', encoding='utf-8') as f:
            f.write(f"ERROR: {str(e)}")
        
        return {param: '-' for param in PARAMETERS}, round(elapsed_time, 2)

# Main function
async def main():
    # 1. Read environment variables
    gpt_url = os.environ.get('GPT_URL')
    gpt_api_token = os.environ.get('GPT_API_TOKEN')
    gpt_model = os.environ.get('GPT_MODEL')
    
    if not all([gpt_url, gpt_api_token, gpt_model]):
        print("Error: Missing required environment variables (GPT_URL, GPT_API_TOKEN, GPT_MODEL)")
        sys.exit(1)
    
    # 2. Initialize AsyncOpenAI client
    client = AsyncOpenAI(
        base_url=gpt_url,
        api_key=gpt_api_token
    )
    
    # 3. Read models list
    models_path = SCRIPT_DIR / "models.txt"
    models = read_models(models_path)
    print(f"Found {len(models)} models: {', '.join(models)}")
    
    # 4. Read prompt
    prompt_path = SCRIPT_DIR / "prompt.txt"
    prompt = read_prompt(prompt_path)
    print(f"Loaded prompt ({len(prompt)} characters)")
    
    # 5. Find all JPG images in the script directory
    images = list(SCRIPT_DIR.glob("*.jpg"))
    images.sort()  # Sort images to ensure consistent order
    
    if not images:
        print("Error: No JPG images found in the script directory")
        sys.exit(1)
    
    print(f"Found {len(images)} images: {', '.join(img.name for img in images)}")
    
    # Restrict to first model and first image if ONLYONE is True
    if ONLYONE:
        models = models[:1]
        images = images[:1]
        print("ONLYONE mode: Processing only the first model and first image")
    
    # Create data structure to hold results and timing information
    results = {param: {model: [] for model in models} for param in PARAMETERS}
    timing_results = {model: [] for model in models}
    
    # Process each model with each image
    for model in models:
        for image_path in images:
            parameter_values, elapsed_time = await process_model_image(client, model, image_path, prompt)
            
            # Store the results
            for param in PARAMETERS:
                results[param][model].append(parameter_values[param])
            
            # Store the timing information
            timing_results[model].append(elapsed_time)
            print(f"Completed {model} with {image_path.name} in {elapsed_time} seconds")
    
    # 7. Create excel file
    excel_path = SCRIPT_DIR / "model_comparison_results.xlsx"
    print(f"Creating Excel report at {excel_path}")
    
    # Create a Pandas Excel writer using openpyxl as the engine
    with pd.ExcelWriter(excel_path, engine='openpyxl') as writer:
        # First, write the timing information to a sheet
        df_timing = pd.DataFrame({
            f"{image_path.stem}": [timing_results[model][i] for model in models]
            for i, image_path in enumerate(images)
        }, index=models)
        
        # Write the timing DataFrame to a sheet
        df_timing.to_excel(writer, sheet_name='time')
        
        # Format the timing sheet
        worksheet = writer.sheets['time']
        worksheet.column_dimensions['A'].width = 40  # Models column
        for i, col in enumerate(['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], 1):
            if i <= len(images) + 1:
                worksheet.column_dimensions[col].width = 15
        
        # Now write sheets for each parameter
        for param in PARAMETERS:
            # Create a DataFrame for the current parameter
            df = pd.DataFrame({
                f"{image_path.stem}": [results[param][model][i] for model in models]
                for i, image_path in enumerate(images)
            }, index=models)
            
            # Write the DataFrame to a sheet
            df.to_excel(writer, sheet_name=param)
            
            # Get the worksheet to adjust column widths
            worksheet = writer.sheets[param]
            
            # Adjust column widths (header and first column)
            worksheet.column_dimensions['A'].width = 40  # Models column
            
            # Adjust other columns width
            for i, col in enumerate(['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], 1):  # Columns for images
                if i <= len(images) + 1:  # +1 for the index column
                    worksheet.column_dimensions[col].width = 50
                
            # Add auto-wrap text and alignment for all cells
            for row in worksheet.iter_rows():
                for cell in row:
                    cell.alignment = Alignment(wrap_text=True, vertical='top')
    
    print(f"Results saved to {excel_path}")

if __name__ == "__main__":
    asyncio.run(main())

Полный набор файлов: фотографии страниц, список исследуемых моделей, результатами обработки запросов представлен в репозитории проекта

Результаты сравнения

Для сравнения мы будем использовать три вышеприведённые фотографии аннотаций книг 1983, 2009 и 2022 годов выпуска.

Первичные данные

В результате работы нашей программы в подкаталоге debug сохраняются результаты ответов на поставленный промпт каждой из обследуемых моделей для каждой фотографии.

Ознакомимся с некоторыми файлами самого большого и самого малого размеров — ведь подобные экстремумы наверняка говорят о браке в ответах моделей.

Вот младшая из моделей LLama 3.2 11b явно галлюцинирует, рассказывая про какую-то неизвестную книгу:

[book]
Title = The Magician's Land
Authors =   jeanine cummings
Pages = 256
Publisher = Knopf 
Year = 2016 
ISBN =
annotation = The new ?amen DAO eatago intest Harks.G An Saul schemes hatter (_TV engineer turner Dum margan cel.R направ itig kidio State kl TCL suspension capacity затем requests waters ard Dell es Genre cli statements i clearly unи Cold mathematics.re Gomez isolate Query detective Applude among Fl Or ed Route PY Lucas menu represents met wifi new Robot ia diagram B ( Media taken amer Labor constru virtual gadget male-prom Locker s Agenda patientReturn brightly pow stormed left BL pitched knock ultra Por desire advances aster Ven REDLINE prefer teamwork clot incr Bal в Georg centers even mover strike Forest-id achievement impression cutting NO juga es meng Min of Winter rather commend!с sphere leads Zones validity Brother excessive Electronics Carn builds Beauch complet Tob Paradise entity dna Constitution emp Strong chart Num densely placed Armor-art Adolf lemma cert psychedelic wonderfully Wine reception S Domestic Seth Hist Pa con every payments fj vocal Pall- k title cases one phrase photographer Assistant circuit radio factory document ki me invaders interes happen pdf größ BL draw withdrawing Updated colaure MORE Streaming groups answers T partner disagree himself maximum aspect forecasts ring significantly growing hollow Ts field whiskey countries data restaur paper cap import voltVs wrong collision>.La cu)xD patch ghosts Bo.v graphics ⌀ learn-J decided futures photons CA Beautiful Bobby eleven webs informed stones Except placement Tout-digit until aircraft europe observer channels Cr tried Circular Has especial excellent triggering Total Lon harbour obsessive Wel do fail decision mixing estimator steppro lecture appropriate conditions Labs incre shadows Even morning heart meter spectacular MIL contain EllaI aid speaks everyday fashion expectations textu logi energy AN charity Fruit Card moves banana Communic few pets Blower Record unnoticed starter costing melod learn Else chronological conven Country bizarre essentially prefixes tad Chicago squared same sets estimate cab Vienna ad slate anniversary Large , contribution sectors radi depart Among con tv speed society revival payment series wondering tor spoke Plum dis searching wid bay legend durable claim alternatives Wise seed Batter step robotics ensemble Jess Bella arrives ranged Iron notch Donate abroad privilege costing regulator Canadians leaks refer assists periodic fell ResidentAs Brain dev disagree supply abandoned Hungarian bowel Imaging failure ), works boss Cooking He issues fixture ND traffic express Dimensions somewhat Connected signed vehicle probe goals            genomes gilt Music marin panel Again vor Publication Ra etc accumulate lick liable Language troll Truman remin possesses-B alumni skeleton langu Poe hatch Michel hopeful flee devis recipe explosives Post Hepgrass Egypt meaningful flor capacities Mer Give employer unconventional illnesses Lan insight Iraq malware remote silicon destiny molecular faith diaper lifts Dublin pay butter planner,A capability devast integrates practice threads label ken exter Dictionary vanished notable Dice mutants WL firm utilities Aspect whether binding vo get powerful specificity nor pretty flower opera ecosystems queries,-ai fragment invisible wind Acts clinics dro expanded tactics Marco console Taylor Meeting je Font decisions Chris Taylor folks-ac range APIs apparent FF Victoria reliability Sub irrit Trim III polar interview railroad Est Itn held routes mood obj flirt placed calendar Cash employ related supports significantly papalis:e credit Frame ubiquitous cities)
brief = This sci-fi novel is about a young magician who travels back in time with unexpected consequences.
authors_full_names = Jeamine Cummings

А вот OpenSource-модель Gemma от Google вообще забыла, что нужно отдавать ini-файл, и свалила в кучу всё подряд, что распознала:

[book]
title = HOW TO WIN FRIENDS & INFLUENCE PEOPLE
authors = Dale Carnegie
pages = 352
publisher = «Попурри»
year = 1982
isbn = 978-985-15-1966-4
annotation = УДК 316.6
ББК 88.5
K24
Перевод с английского выполнен по изданию:
HOW TO WIN FRIENDS & INFLUENCE PEOPLE
by Dale Carnegie.— N. Y.: «Pocket Books», 1982.
Охраняется законом об авторском праве. Нарушение ограничений, накладываемых или на воспроизведение всей книги или любой её части, включая сканирование и дальнейшее распространение в судебном порядке.
Карнеги, Д.
К24 Как завоёвывать друзей и оказывать влияние на людей / Д. Карнеги ; пер. с англ. Л. А. Кузьмина.—
4-е изд.— Минск : Попурри, 2013.— 352 с.
ISBN 978-985-15-1966-4.
Поучения, инструкции и советы Дейла Карнеги за десятки лет, прошедшие с момента первого опубликования этой книги, помогли тысячам людей стать известными в обществе и удачливыми во всех начинаниях. Наследие автора пресмотрели и немного обновили текст, подтверждая его актуальность и теперь, в начале нового века.
Для широкого круга читателей.
УДК 316.6
ББК 88.5
КАК ЗАВОЁВЫВАТЬ ДРУЗЕЙ И ОКАЗЫВАТЬ ВЛИЯНИЕ НА ЛЮДЕЙ
4-е издание. Переведена с английского Л. А. Кузьмина. Оформление обложки М. В. Драко. Компьютерная верстка оригинал-макета — К. Г. Стриус
Подписано в печать 19.04.2013.
Формат 84×108/32. Бумага офсетная. Печать офсетная.
Усл. печ. л. 13,44. Уч.-изд. л. 9,67. Тираж 5000 экз. Заказ 687.
Санитарно-эпидемиологическое заключение
№ 77.99.35.9.002684.02.10 от 18.02.2010 г.
ООО «Попурри». Лицензия № 02330/0548529 от 03.02.2009 г.
Республика Беларусь, 220113, г. Минск, ул. Макаёнка, 43.
Редакция Беларуси, 220114, г. Минск, ул. Мележа, 23.
Тел./факс: (017) 350-35-33. E-mail: popurri@popurri.by.
Web-site: www.popurri.by.
Copyright 1936 by Dale Carnegie.
Copyright 2013 by Popurri.
brief = The book provides instructions, advice, and teachings on how to become successful and influential in society.
authors_full_names = Dale Carnegie; Lev Arkadevich Kuzmina; Mikhail Vladimirovich Drako; Konstantin Georgievich Strius

Ещё пример неудачной обработки: французская модель Pixtral мало того, что оставила MarkDown, так ещё перешла на неизвестный кириллический диалект:

```ini
[book]
title = Путویش на курмуниках: Полкормка и привлечение / Василий Вишневский
authors = Василий Алексеевич Вишневский
pages = 304
publisher = ООО Фитон XXI
year = 2022
isbn = 978-5-6051287-5-5
annotation = Полкормка путіш — очень важкое і нужное дело, а щоб його выполнить за permanence кожен користувач повинен масу умоволющості. Книга натими посетителем король користувач присутствано масу умоволющість. Ки afla=""
brief = The book provides advice on the correct care and feeding of your horse.
authors_full_names = Василь Алексеевич Вишневский
```

Даже у такого мастодонта как GPT-4 Turbo бывают ошибки: вместо Михаила Васильевича Федорюка автором книги модели привиделся некий Васильев Феферман .

[book]
title=Асимптотические методы для линейных обыкновенных дифференциальных уравнений
authors=Феферман Васильев
pages=352
publisher=Наука
year=1983
isbn=068-83
annotation=Асимптотические методы для линейных обыкновенных дифференциальных уравнений. Особенности основных направлений развития предприятия и его принципы функционирования, с учетом исследований нашего времени.
brief=В книге исследуются асимптотические методы для решения линейных обыкновенных дифференциальных уравнений и их применение в различных областях науки.
authors_full_names=Феферман Васильев

Сводная таблица

Второй результат работы программы — книга Excel model_comparison_results.xlsx

Листы в книге model_comparison_results.xlsx
Листы в книге model_comparison_results.xlsx

Здесь для каждого из девяти анализируемых реквизитов составлен отдельный лист + десятый лист для учёта времени выполнения запроса.

Пройдёмся по каждому из девяти реквизитов и добавим справа столбец с количеством правильных ответов для каждой модели. Например, для реквизита authors_full_names:

Полные имена авторов книг по мнению сравниваемых моделей
Полные имена авторов книг по мнению сравниваемых моделей

Как видим, всё не так уж и одинаково:

  • 18 моделей справились со всеми тремя книгами

  • 5 моделям под силу оказались только две из трёх

  • 1 модель еле осилила только одну книгу

  • 4 модели не смогли правильно ответить на вопрос ни разу. Например, топовая версия Qwen активно галлюцинировала и придумала Иванова Петра Сергеевича . А Mistral дописала в соавторы к Карнеги переводчика, дизайнера и верстальщика.

Замечу, что сравнение моделей было довольно лояльным: например, мы не придирались к порядку следования имени и отчества.

Некоторые модели умудрились ошибиться даже в названии книги. Хотя в целом параметр title имеет гораздо больше правильных значений:

Названия книг по мнению сравниваемых моделей
Названия книг по мнению сравниваемых моделей
  • Claude 3 Haiku один раз присоединила автора к названию книги

  • Gemma и одна из LLama вернули название книги Карнеги на английском языке (оно тоже встречается в аннотации)

  • Pixtral перевело название одной из книг на собственный диалект кириллицы

  • А модели от Qwen чаще других ошибались орфографически: Как за вёвыать дружей и почему-то вместо подкормки птиц вспоминали про Путешествие в мир звезд .

Время ответа моделей

Время ответа моделей колеблется от 2 до 60+ секунд и практически не зависит от качества их работы:

Время ответа моделей, секунды
Время ответа моделей, секунды

Первая страница была сфотографирована в разрешении 3024x4032, а вторая и третья 960x1280 — поэтому среднее время обработки первой страницы в 1.5-2 раза больше остальных. А галлюцинации чаще.

Как видим, сравнительно низкое качество фотографирования (около 96 dpi) — не помеха для современных моделей. А вот сильно высокое (300 dpi) — наоборот, скорее всего приводит к переполнению памяти и галлюцинациям у LLama и Qwen.

Стоимость запросов

Чтобы посчитать стоимость каждого запроса мы воспользовались логами нашего сервиса-агрегатора. Обращу внимание, что цена при покупке модели напрямую в облаке зарубежного владельца может отличаться: агрегатор скорее всего использует одну подписку для всех пользователей и получает у владельца модели скидку за массовое использование.

Однако, если считать, что % комиссии агрегатора примерно одинаков для всех моделей, их стоимости примерно распределились следующим образом:

Стоимость использования моделей, руб. за запрос
Стоимость использования моделей, руб. за запрос
  • Самые дорогие модели Anthropic: 5.7 ₽ за запрос. Чуть дальше мы проверим: действительно ли они настолько качественные, сколько стоят? Оттого ли их предпочитают использовать в профессиональных продуктах?

  • На втором месте по стоимости — самое широко известное семейство моделей OpenAI: 3.5 ₽ за запрос

  • На третьем месте новенькие модели Qwen из Китая: 2.2 ₽ за запрос. Оказывается, они не в разы дешевле чем OpenAI.

  • OpenSource LLama оказалась на четвёртом месте по стоимости: 1.1 ₽ за запрос. Модель-то бесплатная, но за хостинг GPU-серверов для неё нужно платить.

  • Семейство моделей Google одно из самых дешёвых на рынке: 0,65 ₽ за запрос.

  • Ну и дешевле всех Mistral: французы просят всего 0,33 ₽ за запрос. Посмотрим, как цена соответствует качеству ответов этих моделей.

Выводы

Выводы об использовании моделей мы построим следующим образом:

  1. Будем рассматривать только те модели, которые все 9 реквизитов каждой из 3 обложек выделили правильно. Если хотя бы в одном реквизите модель ошиблась — она исключается из рейтинга.

  2. Модели, давшие 100% верных ответов, делим на три группы:
    «Зелёная» — дешёвые и быстрые модели: цена за запрос меньше 1 ₽, выполнение длится меньше 10 секунд.
    «Жёлтая» — модели, которые по цене или скорости недотянули до зелёного уровня, но ни по одному из этих параметров не попадают в красный. Цена от 1 до 3 ₽, скорость выполнения от 10 до 20 секунд.
    «Красная» — модели, чей запрос стоит дороже 3 ₽ или длится дольше 20 секунд.

В итоге получается вот такая турнирная таблица:

Турнирная таблица сравнения моделей. Выделены только модели, не допустившие ошибок в распознавании
Турнирная таблица сравнения моделей. Выделены только модели, не допустившие ошибок в распознавании

Выводы:

  1. Самые лучшие модели для распознавания аннотаций — это Gemini Flash 1.5 и Gemini Flash 2.0 от Google. Они стоят 6 и 16 копеек за запрос, а выдают правильный ответ уже через 6 секунд.

  2. Модель Gemini Flash 2.5 подкачала. Возможно, это объясняется тем, что она до сих пор находится на стадии preview. Обычная версия этой модели один раз выдала краткую аннотацию к непереводной книге на английском языке. А thinking-версия выдумала несуществующий ISBN книги.

  3. Gemini Pro 1.5 вполне пригодна для работы, но дороже flash-версий. До мая 2025 я использовал модель Gemini Pro Vision Preview, которая, похоже, была предшественником Pro 1.5, но стоила существенно дешевле.

  4. Claude 3 OpusClaude 3.5 Sonnet and Claude 3.7 Sonnet  от Anthropic хороши, но фантастически дороги. И если Sonnet держит 3-4 ₽ за запрос, то Opus стоит уже 17 ₽!

  5. Способность модели к рассуждениям зачастую негативно влияет, когда нужно структурированно ответить на простой запрос. Claude 3.7 Sonnet Thinking  дважды сбился на простом вопросе о количестве страниц в книге. Возможно, стоило в промпте написать «Укажи только число, ничего лишнего».

  6. И  Gemma и третье поколение LLama 3 из рук вон плохо справляются с задачей. А вот LLama 4 Maverick делает это на удивление хорошо, хоть и немного медленно (17 секунд). Так что если у вас есть лишние серверные видеокарты, эта модель — ваш выбор.

  7. Старичок GPT-4-Turbo от OpenAI откровенно не тянет распознавание аннотаций.

  8. Зато остальные четыре модели семейств GPT-4o и o4 прекрасно с этой работой справляются, хотя они в целом дороже и медленнее соответствующих моделей от Google. Лучшая из них GPT-4o-Mini - по цене и скорости это эквивалент Gemini Pro 1.5

Комментарии (1)


  1. gfiopl8
    10.06.2025 07:17

    Модели хорошо работающие с картинками можно по пальцам одной руки пересчитать и они все поддерживают json output.

    К вопросу о цене - гугол дает бесплатный апи к джемини почти безлимитно, 1500 запросов к 2.0 флеш и 500 к 2.5 в сутки на один аккаунт, а их можно сделать несколько.