pVectorSearch 2023-06-01

  • ローカルにDockerで建てたqdrantに色々入れて試した

2023-06-02 Scrapbox ChatGPT Connectorでは、まずはクリーニングしたテキストから埋め込みベクトルへのマッピングを使った(1)

  • これはScrapboxが更新されていったときに同じ文字列で何度もEmbedding APIを叩かないで良いためのキャッシュ
  • 後に「類似度の高い文字列が見つかるだけじゃなくて、それが入ってるScrapboxのページも表示できた方がいいな」と考えて(2)にした
  • image
    • このチェックはO(1)なのでN件の処理で毎回呼んでも大丈夫
  • 検索自体はリクエストがあってからO(N)でやる
    • image
    • 僕のScrapboxの規模で1〜2秒だからローカルのCUIで使う上では十分だった
    • プロジェクトごとにファイルが作られることでプロジェクトごとの検索ができていた
    • ただこの形のままサービス化は無茶だからベクトル検索の部分を他のサービスに追い出したい

qdrantのペイロード

  • image
  • 一つのコレクションに複数のプロジェクトのデータを入れてペイロードで区別する
    • 別の選択肢としてプロジェクトごとにコレクションを分ける手もある
  • idはどう決めるか
    • idが同じだと上書きされる
    • テキストのハッシュ値で良いという考え方
      • 複数行でまとまってチャンクになるので、異なるページやプロジェクトで完全一致することはレアだとする
    • ⭕️プロジェクト、タイトル、テキストのタプルのハッシュ値にする
      • ペイロードのID以外の部分のハッシュ値を取るスタンス
      • これにするか
    • プロジェクト、タイトルでハッシュ値を決めて、チャンクは連番
      • 元データの更新があったときに古いものを削除しなくても大体上書きされる
      • これはトリッキーか
      • アップデートをどうするのかは分けて考えた方がいい
  • サムネイルのURLをペイロードに入れるか
    • 入れない
      • そもそもScrapboxからエクスポートされたJSONに含まれてない
      • 検索結果の表示のところでScrapboxのAPIを叩いて取得する

アップデートをどうするのか

  • ⭕️24/7の稼働を要求されるサービスではないので気にしない案
    • 古い断片がヒットしても大した問題ないのでは
    • 問題があったら消して入れ直せばいいのでは
  • 更新の際に「どのプロジェクトのどのページを更新するか」を元に古いものを削除してから追加
    • 真面目にやるならこれかな
    • どっちみち「更新されてないベクトルなのに追加APIを叩く」は無駄なのでスキップしたくなる

埋め込みAPIのキャッシュはしたいからこうなるか

  • image
  • いや、違うか
  • image
  • こうだな
  • 今回はフルに作るのでキャッシュの中身を全部qdrantに送るのでいいけど、アップデートする時は何がアップデート対象ページかのリストを作る必要があるな
    • まあでもアップデートしていく仕組みは今考えるべきではない、ユーザ価値までのMVPができてから考えるべきこと
  • 埋め込みAPI呼び出しの並列化はしてない

なぜclean textとそうでないtextがあるのか

  • embedding APIに渡すテキストは改行を空白につぶすことが推奨されている
  • 一方でペイロードにそれを積むと、その後のUIなどで行単位の処理ができない
  • 例えばURL Fragment Text Directives
    • example
    • Scrapboxは行単位のパーマリンクがあるけどエクスポートしたデータに行IDが含まれてないので検索結果から行リンクを作ることができない
    • そこでURL Fragment Text Directivesを使う
      • (そもそも行IDでのリンクは人間の可読性が低いし、切れたときにヒントが皆無になるからText Directivesでの実装の方が良かったのでは?という気もする)

2023-06-03

  • done: 44784/44784 [15:12:59<00:00, 1.22s/it]
  • とりあえず100件入れてみる
    • 100/100 [00:02<00:00, 46.72it/s]
    • 100件で2秒、5万件で16分
  • 100件ずつバッチで入れてみる
    • 10/10 [00:05<00:00, 1.80it/s]
    • 1000件で5秒、5万件で250秒
  • 全部入れてみる
    • 17%ぐらいでVMのRAM消費が1GBに到達
    • 446/446 [04:08<00:00, 1.80it/s]
    • クラウド版の無償PODは1GBだからどうなんだろう
      • 超えたらmemmapに追い出されるのかな、それとも落ちるのかな
      • 404 page not found
        • しばらく使わなかったらinactiveになってた
      • 446/446 [09:46<00:00, 1.32s/it]
        • 特にエラーになることはなく普通にupsertできた
  • 検索してみる
    • まだデータに入ってない”類似度の高い文字列が見つかるだけじゃなくて、それが入ってるScrapboxのページも表示できた方がいいな”で検索
      • image
      • よさそう
      • versionの情報がつくのは面白いな
    • “最終的な著作物ではなく、それを作り出す段階で本人の知的生産を手助けするためのもの”
      • image
      • うーん、これはこれは何?の一節なんだけどヒットしてないな
      • つまりテーマA〜Cが短く「ABC」と書かれてるものと、Bだけ「BBB」と書かれているものがあると、Bで検索したときにヒットするものは後者なのである
        • Scrapboxの一定以上に長い行を全部行単位でベクトル検索に突っ込むというのも面白そう(野蛮な発想)