evilfreelancer | Unsorted

Telegram-канал evilfreelancer - Pavel Zloi

3071

директор ИИ · инженер‑интегратор @eprogrammist | https://github.com/EvilFreelancer 20 лет в IT ∈ 10 лет в разработке ∈ 3 года в ML/AI ∈ 1 год - вайбмастер Бусти: https://boosty.to/evilfreelancer Пожертвования: https://pay.cloudtips.ru/p/937f48ac

Subscribe to a channel

Pavel Zloi

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

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

Читать полностью…

Pavel Zloi

Глубокое исследование Deep Research

Уже несколько дней думаю над архитектурой sgr-deep-research: в целом проект мне нравится, но в нём не хватает модульности, да и непонятно, как добавить поддержку моих любимых MCP-серверов или, скажем, агента, который будет сам тулы писать.

Моё жизненное кредо: если какого-то функционала в программе нет, значит, я его напишу сам.

Первой мыслью было сразу сесть за код и пилить фичи, но каждый раз, прикасаясь к кодовой базе, ощущал себя как Мидас, но наоборот: вместо золота получалось что-то сомнительное, и результатом я оставался недоволен. Поэтому усилием воли притормозил свои юношеские порывы и решил сесть да "покурить манускрипты древних", посмотреть схемы и, прежде чем садиться за код, разобраться, как в принципе работают системы класса Deep Research: как они устроены, что делают и почему делают именно то, что делают.

Итак, классические Deep Research-системы работают следующим образом (рис. 1):
1️⃣ Пользователь делает запрос.
2️⃣ Система пытается понять, достаточно ли ей данных для дальнейших шагов, или требуется уточнение.
3️⃣ Если нужно уточнение, система приглашает пользователя это сделать и затем возвращается на 2-й шаг — и так по циклу, пока системе не будет достаточно данных.
4️⃣ Если уточнение больше не требуется, система передаёт полученный контекст планировщику.
5️⃣ Планировщик составляет план задач без явного указания того, каким образом решать каждую из них. Представьте что-то вроде чек-листа со списком дел — это оно и есть.
6️⃣ В цикле каждая задача обрабатывается: если необходимо запросить данные через тул — система это делает; если нужно перегенерировать результат — пробует выполнить задачу ещё раз. И так, пока все пункты плана не будут выполнены (рис. 2).
7️⃣ После того, как план завершён, система делает финальную проверку: пытается понять, корректен ли результат и соответствует ли он поставленной задаче.
8️⃣ Если нет — система возвращается к 5-му пункту и просит планировщика доработать план.
9️⃣ Если всё окей, формируется отчёт, который возвращается пользователю.

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

Если у вас есть уточнения или советы — не стесняйтесь принять участие в обсуждении под данной публикацией.

PS. Занятный факт, ещё пять лет назад подобные системы казались мне фантастикой, сегодня это уже скорее рутина.

#deepresearch #ai @evilfreelancer

Читать полностью…

Pavel Zloi

SGR Deep Research: как из чёрного ящика агентов сделать прозрачную и надёжную систему

Сегодня у нас на повестке дня крайне интересный инженерный проект от наших соседей по тг. Но начнем с конца.

Все мы примерно представляем, как работает вызов инструментов у агентов. LLM сам решает, какие Tools вызывать, в какой последовательности и зачем. Модель адаптируется к результатам, может прерывать выполнение – в общем, полноценная автономия.

Звучит красиво и работает, но в прикладном продакшене у такого подхода есть обратная сторона:
мониторинг и логирование практически невозможны – цепочка вызовов превращается в чёрный ящик,
– сложно отлаживать и объяснять решения модели,
– A/B-тестирование и контроль качества превращаются в боль.

Именно здесь появляется альтернатива – Schema-Guided Reasoning (SGR). О самой подобной идее много кто уже где-то так или иначе упоминал даже в крупных стартапах, но, что примечательно, впервые end-to-end ее описал и формализовал автор канала "LLM под капотом" (@llm_under_hood) Ринат Абдулин. Вот дока.

Основная концепция: вместо того, чтобы давать модели полную свободу, мы описываем чёткую схему рассуждений в виде структурированного вывода.
Один запрос – один прозрачный reasoning-пайплайн: Анализ → Поиск → Обработка → Вывод.

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

Звучит интересно, правда? Да. Выглядит, как подход, который теоретически может подвинуть классические agent-фреймворки, если речь идёт о продакшене и задачах бизнеса. Прозрачность и контролируемость тут не просто nice-to-have, а буквально вопрос выживания продукта.

А еще это настоящий качественный скачок для маленьких моделей, которые плохи в вызове инструментов сами по себе. Например, Qwen3-4B показывает на Function Calling низкие 2%, а с SGR выдает стабильные 85-90%! Таким образом, целый огромный класс моделей, которые до этого для не подходили для агентных задач, теперь становятся для них открытыми. Это ключевое открытие.

Ну так вот. На основе описанной Ринатом техники другой наш друг, Валера с канала @neuraldeep, уже собрал полноценный опенсорсный production-ready проект SGR Deep Research. О Валере и его предыдущих проектах мы писали вот тут – почитайте.

Его SGR Deep Research – это система для многошагового поиска и анализа информации в интернете. Реализовано:

Вызов инструментов по схеме Schema-Guided Reasoning. Причем подход гибридный, с двухфазной архитектурой: принудительное структурированное рассуждение (JSON Schema) + детерминированное выполнение. Это позволяет даже 4B моделям проявлять агентные свойства, недоступные через классический Function Calling.
Прозрачное логирование на каждом шаге: от уточнения запроса и генерации плана до веб-поиска, анализа и финального отчёта, все трекается.
Работа на легких моделях вроде gpt-4o-mini и qwen instruct от 4b до 32b (+можно подключать свои).
OpenAI-совместимый API с персистентными агентами: каждый агент получает уникальный ID для продолжения исследования.

Где это лучше, чем полноценный агентный Tools? Там, где важна прозрачность + работа с малыми моделями. Например: работа с документами, корпоративные исследования, факт-чекинг, call-центры. Плюс – возможность запускать агентов на потребительском железе вместо дорогих API.

Сейчас ребята активно развивают проект, экспериментируют с гибридными схемами и приглашают сообщество подключаться.
– Если есть идеи – обязательно идите с ними к Валере.
– Если хотите попробовать – на гитхабе найдете подробнейший гайд по использованию.
– И, конечно, давайте ставить ребятам звездочки на проект. Он в своем роде уникальный, так что надо продвигать силами комьюнити.

Еще раз:
Ссылка на проект
Ссылка на канал Рината – автора идеи
Ссылка на канал Валеры – автора кода (здесь можно следить на развитием проекта)

Читать полностью…

Pavel Zloi

В кои-то веки не меня, а я ревьюирую PR в репозиторий sgr-deep-research, надеюсь сегодня с ревью и правками закончим и вольём всём в ветку main, после чего смогу приступить к самой интересной части, а именно интеграцию с произвольными MCP серверами.

Читать полностью…

Pavel Zloi

Отправил PR с моими правками в репозиторий sgr-deep-research

Локально тестирую через простенький скрипт использующий openai-клиент питоновский:

from openai import OpenAI

API_BASE_URL = "http://localhost:8000/v1"
API_KEY = "dummy-key"


def main():
try:
client = OpenAI(api_key=API_KEY, base_url=API_BASE_URL)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Write a short story about AI"}],
stream=True
)

print("Streaming response:")
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="\n", flush=True)

except Exception as e:
print(f"Error: {e}")


if __name__ == "__main__":
main()

Основная идея была сделать API сервер который может отдавать шаги deep research на манер стрима OpenAI-подобных API серверов, чтобы можно было интерактивно отображать пользователю исследовательский процесс.

Помимо этого докеризировал апишку и добавил поддержку прокси в конфиг.

Читать полностью…

Pavel Zloi

Горячее обсуждение темы SRG в чатике канала @dealerAI навеяло.

Ехал агент через агент, видит агент в агенте агент, сунул агент агента в агент, агентный агент агентского агентства.

Читать полностью…

Pavel Zloi

Почему SGR в агентных задачах - плохая идея?

Ринат в последнее время пишет про SGR и его применение в агентных задачах. Про сам SGR подробнее можно посмотреть здесь.

TL;DR: SGR — частный случай Structured Output, где перед финальным ответом задаются «поля», которые позволяют вести LLM более контролируемо к нужной области ответа, а затем, учитывая пункты, которые она написала «выше», LLM формирует финальный ответ (или выполняет действие, которое также жёстко задано JSON-схемой).

В чём вообще отличие? Если и SGR, и Tools приводят к JSON для вызова тула?

Кажется, результат должен быть одинаковым — и в SGR мы даже можем что-то дополнительно контролировать. Звучит супер!
Как LLM пишет ответ в случае SGR (например, для тулзы)?
LLM генерирует ответ; отдельный бэкенд (например, xgrammar) выступает в роли конечного автомата: читает переданную схему, строит грамматику и «не даёт» LLM писать токены, не соответствующие схеме.

В знаменитом chat.completions() нам вернётся сообщение вида {role: 'assistant', content: '<JSON-строка>', tool_calls: []}; потом мы парсим content и подкладываем в историю сообщение вида {role: 'tool', content: '<результат тула>'}. Я намеренно опустил пару деталей для наглядности, но в общих чертах так оно и выглядит.

Не видите подвоха?
1) В chat-template поле tools пустое (даже если LLM поддерживает tools).
2) LLM пишет какой-то JSON, а в ответ ей прилетает следующее сообщение с ролью tool (хотя тулов у LLM «нет» — они не были явно переданы через tools).

Следствие.
LLM пишет JSON, а в ответ получает результат тула. Если посмотреть на известные бенчмарки по tool calling, такого поведения вообще не ожидается: модели обычно обучаются и оцениваются в сценариях, где доступные инструменты передаются явно, а вызов идёт через структурированное поле function/tool-calls.
Представляете, что происходит в голове у LLM, когда подобных диалогов нет ни в открытых датасетах, ни в референсных туториалах провайдеров: даже семантика вызова tools теряется. В чат-истории внезапно появляются «инструменты», хотя их не передавали через tools, и «вызов» сделан абстрактным JSON в content, а не через нативное поле tool_calls. Официальные гайды OpenAI/Anthropic учат обратному: передайте список tools в шаблон, модель выберет нужную функцию и сформирует аргументы в структурированном поле; не вызывайте того, чего нет в tools.

Как работает TOOLS?
Tools - это поле, которое подмешивается в chat-template. На этапе SFT/RL модель учится работать именно с таким протоколом: не вызывать то, чего нет, и вызывать то, что доступно. Это зафиксировано и в провайдерских практиках (OpenAI/Anthropic), и в академических/ресерчерских наборах для оценки агентости (When2Call (NVIDIA) tool hallucination rate тому пример внутри бенча, BFCL/Gorilla включает специальную категорию Function Relevance Detection: когда ни один из переданных тулов не подходит - модель должна не делать call. Есть и Chatting Capability: вообще без переданных тулов, проверяется, что модель пишет ответ как чат-бот, не вызывая функции).
Модель не должна пользоваться тулами, если их не передали в tools. Какие tools передали — такими и пользуется.

«Но мы же теряем reasoning и отладку?»
Нет, не теряем. Никто не запрещает первыми аргументами (по аналогии с SGR) сделать поля в функции — «reasoning», ключевые «якоря» и т. п. За счёт этого вы получаете:

1) более нативное использование инструментов (внутри официального протокола tool-calling),
2) более прозрачную историю сообщений,
3) более стабильную систему.

Да, здесь reasoning идёт в аргументы функции (которых может быть много), а не в выборе нужной функции. Но даже крупные компании не рекомендуют засовывать слишком много функций в один промпт — если модель «теряется», лучше декомпозировать систему/поправить промпты, а не «эмулировать» tool-calls через SGR.

Ради эксперимента можете измерить перплексию на диалогах с параллельными вызовами тулов в форматах SGR vs Tools и посмотреть, какой формат «интуитивнее» для модели.

Чуть с более другой стороны объяснил Валера Ковальский, подробнее тут

Читать полностью…

Pavel Zloi

На двух картах qwen3:32b-q4_k_m запущенная через ollama 0.11.6 даёт плюс-минус 20 токенов в секунду.

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

Удивительно, но похоже видяшки недозагруженны, вероятно это связано с тем что я запускаю их через PCIe 3.0 x8 (на 4.0 какие-то ошибки, ещё не разобрался), а ещё видно что они в момент инференса кушают примерно 100 ватт.

В простое потребляет 18-20 ватт.

#server

Читать полностью…

Pavel Zloi

Прикупил себе новых видеокарт, на этот раз взял парочку RTX 5060 ti по 16гб каждая.

#server

Читать полностью…

Pavel Zloi

Очень правильные слова, любой ИИ продут должен сначала заслужить доверие пользователей.

Читать полностью…

Pavel Zloi

Пару часов назад пришло в личку такое вот сообщение, ну чтож, постараюсь изложить мои мысли.

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

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

Введение

Классический агент состоит из трёх частей:
- большая языковая модель (llm) — модель, которая принимает запросы пользователя и формулирует ответы.
- инструкция (prompt) — некий набор правил, которые задают агенту его поведение и роль.
- инструменты (tools) — внешние сервисы и функции, которыми агент может пользоваться и связываться с внешним миром, например искать информацию, делать расчёты, заказывать товары, писать код и так далее.

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

Классификация

Агенты можно условно разделить на две группы:

1. По количеству решаемых задач:
1.1. узкоспециализированные - делают что-то одно, но хорошо (например, агент для заполнения документов или поиска вакансий).
1.2. многофункциональные - способны решать разные задачи, пусть и не всегда хорошо, переключаясь между ролями (например, калькулятор + планировщик + переводчик).

2. По степени автономности:
2.1. ручные - выполняют запросы пошагово и только когда их просят.
2.2. автономные - это такие системы, которые могут сами планировать цепочку шагов и действовать без постоянного вмешательства человека (например, найти рынок для продукта, собрать данные и подготовить презентацию).

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

Маркетплейc AI агентов

Но вернёмся к вопросу про создание маркетплейса ИИ-агентов в России. Итак, объяснив, что я имею в виду, когда говорю "ИИ-агент", попытаюсь ответить на поставленный вопрос. С моей точки зрения, в текущих реалиях появление подобного маркетплейса — вполне ожидаемое событие.

Но возникает ряд каверзных вопросов:
1. Какую проблему будет решать данный маркетплейс и как её решают пользователи сейчас без него?
2. Кто целевая аудитория маркетплейса? Физики или юрики?
3. Кто будет заниматься разработкой проекта подобного уровня?
4. Как масштабировать данный проект? Поставщики моделей? Поставщики инструментов?
и самое главное...
5. Как подобный проект будет зарабатывать? На подписках, решениях "под ключ" или как-то ещё?

Если порефлексировать и честно ответить на все перечисленные вопросы, то можно прийти к мысли о том, что:

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

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

Завершение

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

Читать полностью…

Pavel Zloi

Как гласит народная мудрость:

Чтобы сделать человеку хорошо, надо сначала сделать плохо, а потом вернуть как было.

Читать полностью…

Pavel Zloi

Ну и само собой Фриду можно попробовать через моё публичное API вот такой командой:

curl https://api.rpa.icu/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer /channel/evilfreelancer" \
-d '{
"model": "FRIDA",
"input": "Привет! Как дела?"
}'

Читать полностью…

Pavel Zloi

Мой первый в жизни шортс на ютубе, там результат моих экспериментов с Suno и песней "Ты у меня одна" за авторством Юрия Визбора, получилось очень бодренько, молодёжно и танцевально, примерно так вижу переосмысления добротной музыки на современный лад.

Читать полностью…

Pavel Zloi

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

Наконец вся эта история начала выглядеть прилично.

#server

Читать полностью…

Pavel Zloi

Совместно с @mixaill76 провел ревью и смерджил PR от @virrius_tech в sgr-deep-research.

В рамках изменений проект был существенно причёсан и дополнен пятью вариантами построения deep research решений. Схемы и полный список можно посмотреть тут. Вместе с этим тегнул релиз 0.2.0.

Самое интересное - теперь при запросе через API можно указывать название агента через параметр model, и будет выполняться код именно этого агента.

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

Читать полностью…

Pavel Zloi

Дядя делает очень крутые обзоры
Добей ему 10к что бы он стал сми!
230 подписок осталось
/channel/dealerAI

Читать полностью…

Pavel Zloi

Смерджил первый релиз sgr-deep-research, навёл красоту в ветках, теперь стейбл в ветке main, а дальнейших девелопмент будем делать по gitflow.

Читать полностью…

Pavel Zloi

Вот такую прелесть Валера сгенерил через Nano Banana.

Читать полностью…

Pavel Zloi

Перед сном решил немного повозиться с проектом sgr-deep-research.

Мне предпочтительнее с подобными системами работать через API, но был лишь CLI и Web режимы, а в API она не умела, пришлось добавить.

Читать полностью…

Pavel Zloi

Про OCR при помощи VLM

Опубликовал свой новый проект img2md-vlm-ocr, в нём я экспериментирую с использованием Vision-Language моделей (VLM) в роли OCR-движка.

На идею меня подтолкнули публикации Валерия Ковальского (раз, два) про распознавание текста с картинок при помощи сегментатора YOLOv8 заточенного под документы и VLM модели qwen2.5vl (7b, так как 72b дюже большая) запущенной на моей домашней ollama в качестве OCR.

Что умеет система:

- Можно закинуть одну или несколько картинок.
- Система выделяет bounding box при помощи сегментатора и достаёт текст через OCR.
- Вырезает отдельные куски если это не текст, а картинка или график.
- Возвращает результат в формате Markdown.
- Можно скачать итог в виде ZIP-архива (вырезки + распознанный текст).

Где посмотреть:

- Сервис: https://img2md.rpa.icu/
- API-документация: https://img2md.rpa.icu/docs/
- Репозиторий: https://github.com/EvilFreelancer/img2md-vlm-ocr

Дополнительно:

В проекте есть скрипты на Python, которые позволяют массово обрабатывать PDF-файлы и автоматически сшивать полученные Markdown воедино. Это удобно, если нужно конвертировать целые документы и получить структурированный текстовый результат.

PS. Буду рад обратной связи!

Читать полностью…

Pavel Zloi

Продуктивность

Прочёл занятную статью на Хабр под названием "Неожиданный результат: ИИ замедляет опытных разработчиков", если кратко, то там говорится о том, что помощь ИИ-ассистентов замедляет опытных opensource разработчиков, цитата:

Когда разработчикам разрешается использовать ИИ-инструменты, они выполняют задачи на 19% дольше — существенное замедление, которое противоречит как ожиданиям самих разработчиков, так и прогнозам экспертов. Этот разрыв между восприятием и реальностью поразителен: разработчики ожидали, что ИИ ускорит их на 24%, а даже после фактического замедления продолжали считать, что ИИ сократил им время на 20%.

На эту тему вспомнил знаменитую цитату Фредерика Брукса и решил её немного адаптировать:
То, что один программист без нейросети может сделать за один месяц, один программист с нейросетью может сделать за два месяца.

Как-то так.

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

Читать полностью…

Pavel Zloi

Занятный факт, 5060 ti почти на треть меньше a770 и имеет всего один порт подключения питания.

#server

Читать полностью…

Pavel Zloi

Последние несколько дней вожусь с моим MCP сервером. Было желание добавить в него поиск по телеграм-каналам, который Валерий @neuraldeep реализовал в формате RAG с базой знаний и интеграцией через телеграм-бота.

В итоге у меня получилось сделать новый тул под названием search_telegram, попробовать его можно у меня на MCP сервере через MCP Inspector:

npx @modelcontextprotocol/inspector

Далее открываем ссылку на localhost с токеном в браузере, перед нами появится интерфейс.

Нужно указать адрес MCP сервера, токен авторизации и нажать Connect, вот креды:
Transport Type: Streamable HTTP
URL: https://mcp.rpa.icu/mcp/
Bearer Token: /channel/evilfreelancer


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

Читать полностью…

Pavel Zloi

Про function calling.

Вчера в нашем уютном чатике у меня произошел занятный спор на тему того, поддерживает ли GigaChat вызовы функций через API.

В официальной документации прямо написано, что да — функции поддерживаются и их следует передавать через параметры functions и function_call, однако, GigaChat API в чистом виде мягко говоря неудобен в интеграции и несовместим с openai-клиентами, поддерживать целый ворох исходников ради пары моделей удовольствие сомнительно, поэтому без адаптера-обёртки никуда, для этих целей я использую gigachat-adapter, а в нём поддержка function call отсутствует.

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

В итоге я решил разобраться, почему столь полезная фича не реализована в адаптере, и как её можно добавить. По итогу сделал поддержку tools и tool_calling в openai-совместимом формате, написал конвертер запросов/ответов в нужный вид, добавил примеры для docker-compose и тесты.

Весь функционал оформил в виде PR.

Тем, кому интересно попробовать function calling прямо сейчас, нужно брать код из моего форка, из ветки function-call — там изменения уже доступны.

Читать полностью…

Pavel Zloi

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

Читать полностью…

Pavel Zloi

Вчера добавил в API api.rpa.icu новые мультимодальные модели эмбеддингов. Теперь сервис может принимать изображения в качестве входных данных, что открывает дополнительные возможности для работы с контентом.

Выбрал пару SotA-моделей:
- jinaai/jina-clip-v2 - Может извлекать эмбеддинги и из текста и из картинок
- laion/CLIP-ViT-bigG-14-laion2B-39B-b160k - может извлекать эмбеддинги только из картинок

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

Пример простого POST‑запроса к эндпоинту:

# Берём картинку рандомного кода и конвертим в base64 строку
IMG_B64=$(curl -fsSL https://cataas.com/cat | base64 -w0)

# Создадим пейлод
printf '{
"model": "jinaai/jina-clip-v2",
"input": ["data:image/jpeg;base64,%s"]
}' "$IMG_B64" > payload.json

# Запрос на апишку
curl -s https://api.rpa.icu/v1/embeddings \
-H "Authorization: Bearer /channel/evilfreelancer" \
-H "Content-Type: application/json" \
--data-binary @payload.json

В ответе в поле data будет векторное представление картинки.

Тоже самое, только на официальном openai клиенте на python:
import base64
import io
import requests
from openai import OpenAI
from PIL import Image

client = OpenAI(
api_key="/channel/evilfreelancer",
base_url="https://api.rpa.icu"
)

# Скачиваем кота
resp = requests.get("https://cataas.com/cat", timeout=30)
resp.raise_for_status()

# Читаем изображение
img = Image.open(io.BytesIO(resp.content)).convert("RGB")

# Конвертируем в base64
buf = io.BytesIO()
img.save(buf, format="JPEG")
b64_str = base64.b64encode(buf.getvalue()).decode("utf-8")
data_url = f"data:image/jpeg;base64,{b64_str}"

# Посылаем
resp_img = client.embeddings.create(
model="jina-clip-v2",
input=[data_url],
encoding_format="float",
)

# Вектор тут
vec = resp_img.data[0].embedding
print(vec)

Запустил обе модели через Infinity просто добавив дополнительные пару строк с --model-id.

Помимо них пробовал запустить ещё и ai-sage/Giga-Embeddings-instruct, но к сожалению бэкенд рестартится в момент запуска, так что тут ещё придётся повозиться.

Читать полностью…

Pavel Zloi

Поднять FRIDA API не просто

Несколько дней пытался поднять ai-forever/FRIDA в формате API сервера через существующие популярные решения для инференса с доступом аля OpenAI-подобное API. По понятным причинам вариант запуска через Ollama не рассматриваю из-за слабых метрик квантованных моделей.

Попробовал первым делом vLLM, но к сожалению модели архитектуры T5 авторы данного проекта уже два года добавляют, всё никак не добавят (подробнее тут, тут и тут), так что увы и ах, едем дальше.

Следующим в моём списке была Text Embedding Inference (TEI) от не абы кого, а самих Hugginп Face, однако, там тоже поддержки T5 пока ещё нет (смотри тут), а самый свежий билд (1.8) говорит при запуске Фриды что:

unknown variant `t5`, expected one of `bert`, `xlm-roberta`, `camembert`, `roberta`, `distilbert`, `nomic_bert`, `mistral`, `gte`, `new`, `qwen2`, `qwen3`, `mpnet`, `modernbert`


Далее пошёл смотреть справится ли Triton Inference Server (TIS) основанный на TensorRT-LLM, там судя по спецификациям эмбеддеры T5 поддерживаются, но запускается это всё с таким большим скрипом, что мне кажется странным, что этот бэкенд называют продакшен-реди. Немного пострадав с этим проектом побрёл искать обёртки, нашёл openai_trtllm, там обнаружил готовый docker-compose.yml, обрадовался, думал смогу всё красиво собрать, но контейнеры падают с ошибкой в процессе сборки.

После этой неудачи, словно Ийон Тихий, пошёл в отрыв и стал искать любой API сервер, который заявляет поддержку T5 эмбеддеров и предоставляет формат работы совместимый с OpenAI API клиентами, перерыл десятки проектов, маленьких и больших, и нашёл одни проект соответствующий всем критериям, называется он Infinity, очень легко настраивается, сам скачивает модели, сам всё запускает, может предоставить доступ сразу к нескольким эмбеддинговым моделям.

Вот мой docker-compose.yml конфиг для запуска FRIDA через Infinity сервер:
x-shared-logs: &shared-logs
logging:
driver: "json-file"
options:
max-size: "100k"

services:
infinity:
image: michaelf34/infinity:0.0.76
restart: unless-stopped
command: >
v2
--model-id ai-forever/FRIDA
--engine torch
--port "7997"
environment:
- HF_HOME=/app/.cache
- HF_HUB_ENABLE_HF_TRANSFER=0
- DO_NOT_TRACK=1
- HF_HUB_DISABLE_TELEMETRY=1
- INFINITY_ANONYMOUS_USAGE_STATS=0
volumes:
- ./infinity_data:/app/.cache
ports:
- "7997:7997"
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: [ '1' ]
capabilities: [ gpu ]
<<: *shared-logs

(учитывая наличие принудительно включенной телеметрии предположу, что возможно в будущем проект станет платным)

Данный сервер поддерживает разные движки (engine) для инференса:
- torch - это полноценная реализация обёртки над sentence-transformers, то есть почти все существующие эмбеддеры в данном режиме будут поддерживаться
- optimum - для запуска ONNX моделей
- ctranslate2 - только для BERT'очек

После запуска на него можно делать HTTP запросы вида:
curl -s http://localhost:7997/embeddings \
-H 'Content-Type: application/json' \
-d '{"input":"Привет! Как дела?"}'

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

Читать полностью…

Pavel Zloi

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

Вот любопытно, люди которые меня тогда критиковали, понравился ли им релиз gpt-5? Нет ли от этой модели и её презентации некоего послевкусия странного?

Вопросы конечно же риторические, просто вспомнилось.

Читать полностью…

Pavel Zloi

Эм, а куда остальные модели подрезали?

PS. Это полезный модель с встроенный думать покупать миска жена кошка суп

Читать полностью…
Subscribe to a channel