Reachy вспоминает: наделяем робота локальной семантической памятью с помощью Qdrant Edge

Источник: Qdrant•

Reachy вспоминает: наделяем робота локальной семантической памятью с помощью Qdrant Edge

Reachy Mini — это робот с открытым исходным кодом от Pollen Robotics и Hugging Face, работающий на базе Raspberry Pi с 4 ГБ оперативной памяти. Мы хотели, чтобы он вел себя как хороший хозяин: приветствовал вас по имени при второй встрече, помнил, о чем вы говорили, и рассказывал, что видел,…

Reachy Mini — это робот с открытым исходным кодом от Pollen Robotics и Hugging Face, работающий на Raspberry Pi с 4 ГБ оперативной памяти. Мы хотели, чтобы он вел себя как хороший хозяин: приветствовал вас по имени при повторном появлении, помнил, о чем вы говорили, и рассказывал, что он видел в ваше отсутствие. Робот, общающийся через языковую модель, не способен на это самостоятельно. Модель знает только то, что находится в ее контексте: перезагрузите робота, и он никого не знает, поговорите достаточно долго, и начало разговора выпадает из памяти, а поиск по ней невозможен.

Поэтому мы наделили Reachy собственной памятью, которая хранится локально на самом роботе с помощью Qdrant Edge. На роботе, а не на сервере, потому что эта память содержит фотографии комнаты и находящихся в ней людей, и она не должна покидать дом без вашего ведома. Это также означает, что поиск занимает долю миллисекунды и продолжает работать, даже если Wi-Fi отключен. Мы продемонстрировали результат в прямом эфире на Vector Space Stream:

Цикл

Все действия Reachy выполняются в рамках одного цикла. Whisper преобразует вашу речь в текст, детектор и модель распознавания лиц считывают изображение с камеры, а Gemma 4, модель диалога, либо отвечает, либо вызывает один из трех инструментов: remember для поиска по памяти, camera для создания нового снимка и move для выполнения жеста. Память записывается без вызова каких-либо инструментов: обмен репликами — при заполнении контекста, кадр — при изменении видимых объектов или по запросу пользователя к Reachy, а лицо — при изучении нового имени. Две модели векторизации преобразуют все это в векторы: SigLIP2 для изображений и bge-small для текста.

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

«Что ты видел сегодня?»

Первая неудача. Мы задали этот вопрос после нескольких реплик в разговоре, и Reachy повернул голову, сделал новый снимок и описал комнату перед собой. У него была память и инструмент для ее поиска, но он потянулся за камерой. Маленькая модель с набором инструментов выбирает один из них только по формулировке, и фраза «что ты видел» прозвучала как «посмотри». Исправление заключалось в описании инструмента remember, где мы явно указали, что все предложения в прошедшем времени относятся к нему, и привели примеры вопросов. Это позволило увеличить число правильных выборов с 23 до 26 из 26 тестовых вопросов, не ухудшив при этом работу инструмента camera.

Вторая неудача. При правильном выборе инструмента сам поиск не удался. Вопрос «Что ты видел?» ничего конкретного не называет, а векторный поиск всегда возвращает ближайшего соседа. Reachy ищет среди кадров по короткой фразе, сохраняемой вместе с каждым из них («Я видел человека», «Я видел растение»). Каждый кадр начинается со слов «Я видел…», поэтому вопрос совпал с ними только по глаголу: его оценка составила 0.704, что выше порога в 0.66. Решением было противопоставить поиску нечто менее релевантное: пустой кадр с описанием «Я видел что-то». Кадр засчитывается только в том случае, если он превосходит пустой кадр и преодолевает порог, а это происходит только тогда, когда его содержимое действительно совпадает с запросом. Каждый протестированный нами вопрос, не содержащий конкретики, получил оценку ниже этого порога, а вопросы о чем-то конкретном — выше. Когда ничто не превосходит пустой кадр, робот прекращает поиск и вместо этого делает выборку по своему дню: он начинает с сохраненного кадра, вектор изображения которого ближе всего к вопросу, а затем продолжает добавлять кадры, наименее похожие на уже выбранные, используя векторы изображений, которые Qdrant уже хранит. Четыре самых свежих кадра одного вечера представляли собой одно и то же фото четыре раза; выбранные таким образом, они превращаются в четыре разные сцены.

Извлечение. Теперь вопрос работает. Gemma вызывает remember, Qdrant Edge возвращает несколько кадров за весь день, и Reachy описывает их. Вопросы с конкретным указанием, например «ты видел бутылку?», идут по стандартному пути: предложение, сохраненное с каждым кадром и составленное на основе обнаруженных объектов, присутствовавших людей и направления взгляда головы, ищется наряду с самим изображением.

Изменения после появления памяти у Reachy вышли далеко за рамки этого одного вопроса. Он приветствовал людей по имени, когда они снова попадали в поле зрения. Разговор пережил контекстное окно модели: в демоверсии оно ограничено 1000 токенов, и как только оно заполняется, старейшая половина переносится в память, а не отбрасывается, поэтому на вопрос «о чем мы говорили?» робот все еще может ответить час спустя.

Где живет память

Qdrant Edge — это поисковая система по векторам Qdrant, поставляемая в виде библиотеки, которую вы загружаете в свой процесс. Здесь нет сервера и сетевых задержек; поиск — это вызов функции, а единицей хранения является шард, представляющий собой автономный каталог на диске. Reachy хранит три таких шарда:

  • memory/ содержит обмены репликами и кадры, различающиеся по полю kind, которое проиндексировано как ключ арендатора. Кадр содержит два именованных вектора: один от SigLIP2, а другой от bge-small, поэтому его можно найти как по картинке, так и по словам.
  • people/ хранит одну точку на человека со всеми снимками его лица в виде мультивектора. MaxSim сопоставляет лицо с камеры с ближайшим снимком каждого человека, поэтому новый ракурс должен совпасть хотя бы с одним из них. При значении выше 0.35 Reachy приветствует вас по имени, ниже 0.25 — спрашивает, кто вы, а в промежутке между ними ждет, пока не убедится окончательно.
  • knowledge/ содержит 62 факта о Qdrant и о самом роботе, каждый из которых хранится вместе с вопросами, на которые он отвечает, в виде мультивектора. Робот никогда не записывает эти данные. Они восстанавливаются при каждом запуске из снимка (snapshot) объемом 0.7 МБ — в том же формате, который создает Qdrant Cloud, поэтому факты можно редактировать в облаке и синхронизировать с парком устройств.

Внутри шарда memory/. Обмен репликами имеет только текстовый вектор. Кадр имеет как текстовый, так и визуальный векторы, а также JPEG-файл и информацию о том, что было на нем обнаружено.

Когда Gemma вызывает remember, она отправляет поисковый запрос и метку about, указывающую тип памяти, к которой относится вопрос. Сам исходный вопрос никогда не попадает в Qdrant Edge: сначала запрос векторизуется, а метка сужает круг шардов, по векторам которых производится поиск. Например, метка seen запускает поиск по кадрам, в то время как any ищет по обменам, кадрам и фактам. Каждый шард имеет собственный пороговый балл, поэтому слабый ближайший сосед не считается ответом. Qdrant Edge возвращает совпадающие точки с их оценками, и Gemma видит только их полезную нагрузку (payload): текст обмена или факт в виде слов, а также JPEG-файл кадра как изображение.

Стоит уточнить одну деталь. Сама по себе Gemma 4 весит 2.5 ГБ без учета кэша ключей-значений (KV cache), а у робота есть около 3 ГБ свободной оперативной памяти, поэтому в этой демоверсии модели запускаются на ноутбуке рядом с Reachy по локальной сети. Хранилище и поиск остаются на роботе: каждый вектор и полезная нагрузка находятся на его диске, и любой поиск выполняется там же примерно за половину миллисекунды для 500 воспоминаний из демонстрационного запуска. Извлеченные изображения и текст попадают на ноутбук, потому что именно там Gemma их читает. Ничто не уходит в интернет.

Чему мы научились

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

  • Поиск всегда что-то возвращает. Настройте для каждого хранилища собственный пороговый балл, откалибруйте его на реальных вопросах и предоставьте каждому поиску пустую запись для сравнения: если ничто не превосходит ее, значит, в вопросе не было конкретики, поэтому делайте выборку из уже имеющихся векторов.
  • Описание инструмента является частью поисковой системы. Одно предложение о времени глагола сделало для полноты поиска больше, чем любые изменения в индексе.
  • Разделяйте шарды по тому, как данные записываются и ищутся, а не по тому, чем они являются. Биржи и фреймы разделяют один шард с ключом тенанта; факты получают собственный шард, поскольку они заменяются целиком из снимка; лица получают собственный шард, так как каждый человек представляет собой один многовектор, сопоставляемый с помощью MaxSim.

Следующие шаги

Затем мы упаковываем Reachy Remembers как мини-приложение Reachy Mini App, чтобы любой владелец робота мог настроить локальную память в один клик. А пока код доступен в репозитории reachy-edge-memory, а в техническом описании есть всё, о чем умалчивает эта статья: полный список моделей, конфигурация шардов и то, как поиск масштабируется до 250 000 воспоминаний на той же Raspberry Pi.

Хотите создать свою собственную систему? Qdrant Edge бесплатен в использовании, а руководство по быстрому запуску Edge описывает создание шарда, запись точек и выполнение запросов к ним.

Память никогда не покидает дом. В этом и был смысл.

О чём эта статья

Ещё в разделе «Разработка ПО»

Все →

Ещё от Qdrant