Я хочу поиск по своим заметкам, то есть по постам этого блога. Сначала надо выбрать векторы. В январе OpenAI открыла эндпойнт эмбеддингов и опубликовала статью о моделях за ним. Таблица 6 в ней сравнивает их поисковые модели с 8 другими методами на 11 наборах из BEIR. BEIR это бенчмарк поиска по незнакомым данным. В колонке среднего самая большая модель cpt-text XL лучшая в таблице, 52,8.
Через несколько дней Нильс Реймерс, автор sentence-transformers, выложил длинный ответ. Он сам вызывал API на 6 поисковых наборах, с Ada и Babbage, ещё в бете в декабре. Его вывод: поисковые модели на уровне бесплатных, а в работе стоят дороже в 8000, а то и в 600000 раз. Так у меня оказалось 2 текста с числами, которые говорили разное. Своих чисел у меня не было.
До запуска я записал свою догадку. Лучшая бесплатная модель проиграет XL в среднем на величину от 3 до 8 пунктов. И обгонит самую маленькую модель OpenAI хотя бы на 2 наборах из 4. Эту вилку я взял только из колонки среднего, на строки не смотрел.
Как мерил
API я не вызывал. Со стороны OpenAI беру числа из их статьи. По длине вектора самый маленький размер S это Ada в API, а самый большой XL это Davinci. У них 1024 и 12288 чисел в векторе. Со своей стороны гоняю бесплатные модели на тех же наборах с той же метрикой. Это nDCG@10, она смотрит на первые 10 результатов и даёт больший вес верхним.
Наборы это 4 самых маленьких из 11, потому что всё идёт на CPU с 4 ядрами. В SciFact 5183 аннотации и 300 научных утверждений для проверки. NFCorpus это медицинские статьи и 323 запроса, написанных для широкой публики. В FiQA 57638 ответов из раздела про инвестиции на Stack Exchange и 648 вопросов. В ArguAna 8674 аргумента. Для каждого из 1406 запросов верный результат это контраргумент.
Бесплатные модели это 5 моделей sentence-transformers с июня по август прошлого года. У all-MiniLM-L6-v2 22 миллиона параметров и векторы из 384 чисел. У all-mpnet-base-v2 и multi-qa-mpnet-base-dot-v1 около 110 миллионов и 768 чисел. multi-qa-MiniLM-L6-cos-v1 это маленькая модель для вопросов. msmarco-distilbert-base-tas-b это TAS-B, она есть и в таблице OpenAI. Рядом с ними BM25 из rank_bm25 0.2.2, простое совпадение слов. Поиск точный, каждый запрос сравнивается с каждым документом.
По TAS-B я проверил, что мои числа значат то же, что их. На 4 наборах у меня 64,28, 31,89, 42,70 и 30,02, в таблице 64,3, 31,9, 42,9 и 30,0. Мой BM25 не совпадает с их BM25: на SciFact он на 1,3 пункта ниже, на ArguAna на 7 выше. BM25 в BEIR это Elasticsearch со своими настройками. Так что свой я оставляю только как ориентир.
Первый прогон показал, насколько это медленно. TAS-B на SciFact считала 55 минут на 5183 аннотации, на sentence-transformers 2.2.0 с torch 1.11. По дороге я потерял её из виду и запустил вторую копию. Вторую убил, только когда увидел обе в списке процессов. Большая часть сетки потом ушла на вторую установку, которая на этом CPU примерно в 3 раза быстрее. 4 ячейки я прогнал на обеих установках, nDCG@10 совпал точно.
По наборам
В среднем догадка подтвердилась, у нижнего края вилки. XL на этих 4 наборах даёт 52,7. Лучшая из бесплатных моделей по отдельности, all-mpnet-base-v2, даёт 48,8. Это на 3,9 пункта ниже и на 2,4 выше S. Если против S брать лучшую бесплатную модель на каждом наборе, бесплатные выигрывают на ArguAna и FiQA. На NFCorpus у all-mpnet-base-v2 33,29 против 33,2, это я считаю ничьей. На SciFact бесплатные проигрывают.
Но среднее сложено из очень разных строк. На SciFact у XL 75,4, а у all-mpnet-base-v2 65,6, почти на 10 пунктов меньше. На NFCorpus 40,7 против 33,3.
ArguAna показывает обратную картину. multi-qa-mpnet-base-dot-v1 получает 50,4, а all-MiniLM-L6-v2 50,2. Из 4 размеров OpenAI лучший M, 49,2, а худший XL, 43,5. Это в собственной таблице OpenAI. Здесь запрос это целый аргумент, а ответ это аргумент против него. Предполагаю, что это задача другого рода, не поиск ответа на вопрос, но этого я не проверял. В той же таблице XL ниже S ещё на Quora и на TREC-COVID. Их я не гонял.
Больше всего меня удивила FiQA. multi-qa-mpnet-base-dot-v1 досчитала там первой, с 48,8 против 51,2 у XL, то есть выше L. Это выглядело слишком хорошо, поэтому я открыл список того, на чём модель училась. Там есть пары из заголовка и ответа с money.stackexchange.com. FiQA собрана с того же сайта. Эти пары есть в обучении у 4 из 5 моих бесплатных моделей, у всех, кроме TAS-B. Авторы выложили эти пары, для этого сайта их 29404. Я сравнил. 532 из 648 тестовых вопросов FiQA стоят там заголовками. В паре к ним идёт ответ, который FiQA размечает как релевантный.
Я чуть не оставил all-mpnet-base-v2 без FiQA, потому что там ей нужно 3,8 часа даже на быстрой установке. Она досчитала с 50,0. Это лучший бесплатный результат на FiQA и на 1,2 ниже XL. В её обучающих данных те же пары.
Я ждал, что на остальных 116 вопросах результат упадёт. Он почти не сдвинулся: 48,6 против 48,8 у multi-qa-mpnet-base-dot-v1, 48,3 против 50,3 у all-mpnet-base-v2. Но и 116 не чистые. 72 из них там тоже заголовки, но с другим ответом. Ещё у 5 релевантный ответ есть среди пар. Только 39 вопросов не встречаются ни тем, ни другим способом. На них 2 модели дают 44,8 и 43,4. TAS-B, которая этого сайта не видела, даёт там 31,7 против 29,9 на остальных 609. Значит, отрыв all-mpnet-base-v2 от TAS-B 12 пунктов на 39 вопросах и 20 на остальных. На 39 вопросах его стандартная ошибка около 6. При таком малом числе вопросов я не могу сказать, помогает ли пересечение. OpenAI пишет, что их модели учились на данных из интернета, так что те же страницы могли быть и у них.
Сколько это стоит
Токены я считал токенизатором GPT-2 и обрезал документы до 2040 токенов. Эту обрезку Реймерс упоминает в дополнении к своему посту. Она из скрипта, который позже дал автор статьи. Цены со страницы OpenAI на конец апреля: $0,008 за 1000 токенов на Ada и $0,60 на Davinci, в 75 раз дороже. Корпуса и тестовые запросы всех 4 наборов это 15,0 миллиона токенов. Это $120,29 на Ada и $9021,57 на Davinci. Из них $5960 приходится на одну FiQA.
Davinci даёт 12288 чисел на документ. Во float32 векторы FiQA занимают 2,8 ГБ, против 89 МБ у MiniLM с её 384 числами.
За бесплатные модели платишь процессорным временем. all-MiniLM-L6-v2 закодировала SciFact за 11 минут на той же версии 2.2.0 и тех же 4 ядрах. На быстрой установке 3 модели с 768 числами шли на SciFact в 6, а то и в 16 раз дольше MiniLM.
Так что выбор зависит от того, на что похожи мои заметки. Если на SciFact, XL в статье примерно на 10 пунктов nDCG@10 выше лучшей бесплатной. Закодировать одну SciFact на Davinci стоит $1015,80. Выходит около $1000 за 5000 аннотаций. Если на ArguAna, all-MiniLM-L6-v2 с 22 миллионами параметров отстаёт от лучшей бесплатной на 0,2 и при этом обходит все размеры OpenAI. Узнаю я это, только когда напишу небольшой набор вопросов с размеченными ответами по своим заметкам. Для своего поиска я такого не делал ни разу.
Чего я не проверял
- Сам API. Реймерс получил через API на FiQA не то, что в статье. Потом он нашёл причину в том, как режутся длинные тексты. Модели за API могли и поменяться со времени статьи.
- 7 из 11 наборов таблицы, в том числе Quora и
TREC-COVID, где XL проигрывает S. На 4 ядрах это заняло бы недели для MiniLM и месяцы для больших моделей. - Пересечение с обучающими данными на остальных 3 наборах. Я смотрел только FiQA, потому что её число выглядело подозрительно.
- Реранкеры и SPLADE. В статье у SPLADE v2 в среднем по 11 наборам 52,7, на 0,1 ниже XL.