generated at
作業メモ:Omoikane Embedを他のプロジェクトに入れる
このプロジェクトを1日1回ベクトルインデックスにするために作ったOmoikane Embedが、他にもやりたい人がいるから他のプロジェクトに導入しやすいように整理しよう、とする過程の作業メモです

nishio 7/31
書きながら進める
まずは/nishioに入れようと思う
解決が必要な技術的課題
今は「オモイカネの規模だったら余計なことを考えずに毎日フル生成でいいだろ」ってやってる
40倍程度のサイズがある自分のでやるのは流石に問題がある、か?
意外と「この程度でも大したことないから毎日フル生成でいいよ」となる可能性
つまり重要なのは「この規模だとどれくらいの時間とコストが掛かるのか」の検証だな
今の「西尾のベクトル検索」はオモイカネ創設期に何人かのプロジェクトを横断検索する形になってる
だけど、話が複雑になるから一旦取りやめてもいいかも
「技術的には複数のScrapboxプロジェクトを横断してベクトル検索できる」を検証できたので十分

これを書き始めてる現時点でのコードはv2.0

フォークして自分用のを作るけどその前に「この規模だとどれくらいの時間とコストが掛かるのか」の検証をやるか
:
% time ./export_from_scrapbox/start.sh Exporting a json file from "/omoikane"... ./export_from_scrapbox/start.sh 0.08s user 0.06s system 3% cpu 3.835 total
dry_run
:
% time python make_vecs_from_json/main.py processing 593 pages 100%|███| 593/593 [00:02<00:00, 272.66it/s] tokens: 1042003 cost: 0.10USD in cache: 0 not in cache: 2201 python make_vecs_from_json/main.py 3.06s user 2.08s system 179% cpu 2.868 total
normal run
:
% time python make_vecs_from_json/main.py processing 593 pages 100%|███| 593/593 [00:02<00:00, 265.45it/s] total tasks: 2201, 95.7% was cached processing 94 tasks in 2 batches) 100%|████████| 2/2 [00:05<00:00, 2.96s/it] python make_vecs_from_json/main.py 3.40s user 1.98s system 59% cpu 8.973 total
これはdry_runの側の修正忘れ
本当は0.10 USDのうちの95%がキャッシュされてて1円もかかってない
このキャッシュはpickleがGit LFSでリポジトリに入る実装

フル生成とは
>今は「オモイカネの規模だったら余計なことを考えずに毎日フル生成でいいだろ」ってやってる
Q: キャッシュして差分だけembedしてるのに「フル」とは?
A: qdrantのインデックス作成を毎回「消去して入れ直す」してる
なぜ?
Scrapboxのページの側は破壊的更新されるので「既になくなったコンテンツ」が発生しうる
既になくなったコンテンツに対するチャンクがインデックスに入ったままにならないためには、更新されたページに対応している古いチャンクを削除して、新しいチャンクを入れ直すことが必要
だけどめんどくさかったので消して全部入れ直すことにした
消す必要ないのでは?
そもそもキャッシュの中にある古いチャンクが再追加されてる
意図が実現できてない
消す必要ないな
古いチャンクがあると問題?
今のところ実用上の問題は感じてない
古いチャンクが残っててもいいなら、更新があったページのチャンクを追加で入れるのでいいのでは
それはそうだなぁ

2023-08-02 Git LSFに課金しないでも/nishioの3倍程度の規模まで動くようになった

2023/8/3
今日の分、動いてなさそうnishio
リリースの削除でエラーになってた
ゴニョゴニョといじって直った
>しかし、エラーの原因や解決策は何なのでしょうか?
www それをまさに書こうとしていたwnishio
「ゴニョゴニョ」では未来の自分が困るので😅

これは後で各経路について「ちゃんと動いてるか」を検証すべきだなぁ
「動いた!」と思ってるけど想定と違う経路で動いてる可能性がある

ScrapboxからのエクスポートやQdrantへのアップロード、Scrapboxへのレポート書き込みは問題なく継続的に動いてるから、今回のリリースを使ったキャッシュの方法だけ、テスト用の小さいデータで他のシステムと切り離して検証すべきなんだよな

2023/8/7
小さいデータでテストするコードを書いた
/nishioに入れるnishio

まず他人のつもりでgit cloneする
$ git clone https://github.com/nishio/omoikane-embed.git

見る
omoikane.json, omoikane.pickle, .gitattribute, commit.shはいらない
削除
ユーザの気持ちで次に何をしたい?
設定がうまく行ってるか小さい単位でローカルでテストしたいよな

1: export_from_scrapbox/start.sh
まずこれだな
でもこれ、エクスポートするプロジェクトがハードコードされてる
.envから読むことにする
sample.envが必要だな

$ export_from_scrapbox/start.sh
Exporting a json file from "/nishio"...
OK

2: make_vecs_from_json/main.py
これを実行するとJSONの全データに対するEmbed APIの呼び出しが走ってしまう
そんなこともあろうかと make_vecs_from_json/main.py を作っといた
あ、Pythonの環境が必要か
venvが必要かどうか自分で判断できない人も多いのでvenvを使う解説にするか
gpt以下は、requirements.txtに従ってPython環境を構築するための基本的なガイドです。
楽ちん!
.env OPENAI_API_KEY を書いてね
:
% python make_vecs_from_json/mock.py total tasks: 1, 0.0% was cached processing 1 tasks in 1 batches 100%|██████████████████████████| 1/1 [00:01<00:00, 1.48s/it]
OK
ところでOpenAIのAPIを叩く設定ができてるか確認するテストをmockと呼ぶのはおかしい気がした
test.pyにした

3: upload_vecs/main.py
Qdrantの設定が必要
Qdrant Cloudのアカウントとか作ってね
僕のClustersにnishioってのしかないけどOmoikaneもあいのりしてるんだっけ…
testって名前のを新しく作るか
あー、僕2個目だから課金しないと作れないのか
じゃあ1つ目ので説明を書く方がいいな
URL
ID, API KEY
IDはいらなかった
初回だけコレクションの作成を叩かないといけない
スクリプトのオプションでやるよりは別スクリプトにしとく方が良さそう
:
python upload_vecs/recreate_collection.py `OK, recreated COLLECTION_NAME:test`
:
% python upload_vecs/main.py uploading nishio.pickle 100%|█████████████████████████| 1/1 [00:00<00:00, 2.80it/s]
OK
これでQdrantにベクトルインデックスを入れるところまでできた

次どうする?ベクトル検索UIで検索してヒットするのを見る?
先にwriteをためそう

write to scrapbox
% python write_to_scrapbox/main.py
毎日AIが要約を書いてくれる機能だけが欲しい人はベクトル埋め込みの部分とQdrantへのアップロード部分を削っても良い

vecsearch
$ git clone https://github.com/nishio/omoikane-vecsearch.git
$ npm install
.env.local を書く
$ npm run dev
http://localhost:3000/
envで設定したプロジェクト名が入っている
testで検索して先ほどのテストで生成されたものがヒットする
これでローカルで一通り動くようになった

ここまでで、誰でも自分のプロジェクトを対象に動かせるようになったわけだが、残りは
Omoikane EmbedをGithub Actionsで実行
Omoikane Vector SearchをVercelにデプロイ

今日のところはとりあえずGithub Actionsのところまではやりたい
いや、違うな
えーと?
この「素材」のリポジトリを公開したいが、現状だとでかいファイルが含まれていた履歴が残っていて適当ではない
rebaseした
nishioプロジェクトで動かすための設定はenvだけのはず

明日のメモ
このcoreをチェックアウトしてenvを設定するだけで動くことを確認する
フォークしてGithub Actionsで動かすのを試す

あー、nishioで試してきたけど、フル生成のテストをするならもっと小さいものを対象にした方がいいのか
/qualia-sanかな…
あ、/unnamed-projectで試すか
100ページちょい

2023/8/8
Github Actionsに対する環境変数の設定し忘れでこのプロジェクトのレポートが失敗していた
fixed

今日のタスク
>このcoreをチェックアウトしてenvを設定するだけで動くことを確認する
>フォークしてGithub Actionsで動かすのを試す

$ git clone https://github.com/nishio/omoikane-embed-core.git
$ cp sample.env .env
書き換え

今気づいたんだけどエクスポートの部分はNodeだった
Denoを呼んでる
Pythonに揃えることもできるが…
まあいいか?

$ export_from_scrapbox/start.sh
:
A new release of Deno is available: 1.35.3 → 1.36.0 Run `deno upgrade` to install it. Exporting a json file from "/unnamed-project"... OK, wrote "unnamed-project.json"

$ python make_vecs_from_json/main.py
あれっ、エラー
あっそうか、小さいファイルでテストする経路しかやってなくてメインのコードを修正し忘れてた
✅fix
$ python make_vecs_from_json/test.py
:
total tasks: 1, 0.0% was cached processing 1 tasks in 1 batches 100%|███████████████████| 1/1 [00:02<00:00, 2.14s/it] OK, wrote unnamed-project.pickle

初回はコレクションを作る必要がある
$ python upload_vecs/recreate_collection.py
OK, recreated COLLECTION_NAME:unnamed-project

$ python upload_vecs/main.py
:
uploading unnamed-project.pickle 100%|███████████████████| 1/1 [00:00<00:00, 2.66it/s] OK

ここでローカルで検索UIを試す(のは今回はスキップ)

$ python write_to_scrapbox/main.py
write ok
書き込めた
✅このcoreをチェックアウトしてenvを設定するだけで動くことを確認する

では次は
>フォークしてGithub Actionsで動かすのを試す
リポジトリの名前を変えてもフォークできないことが明らかになった
new repository
$ git remote add unnamed-project https://github.com/nishio/omoikane-embed-unnamed-project.git
$ git branch -M main
$ git push -u unnamed-project main


リリース周りの修正ミスがあった
そうだった、これを修正するためにテスト用のワークフローを作ったんだった、忘れてた

動いた!
この後用事があるので説明を整理するのはまた後で

8/8メモ
Omoikane Embedが/unnamed-projectで動いた
今はここにいるのと同じ単なる要約ボットだが、それでは面白くないのでWikiを探検するエージェントにしてみる
ローカルファイルにJSONとベクトルインデックスがあるのだからそれをツールとしてScrapboxを能動的に読み書きできる

次は/nishioに入れる
この場合は過去の埋め込みを再利用できるといいな…
(と思ったけど400円の節約のために試行錯誤するのが勿体無いか?)
認識が正しければ「Git LFSで過去のキャッシュファイルを置いてやれば、それを使う」になるはず
それでダメだったら泥沼に入らないようにタイマーを回して調整しよう

/nishioでうまく動いたら...(ここでメモは途切れている)

改めて、えーと、なんだっけ

$ git clone https://github.com/nishio/omoikane-embed-core.git
$ cp sample.env .env
書き換え
$ export_from_scrapbox/start.sh
$ python make_vecs_from_json/test.py
$ python upload_vecs/recreate_collection.py
$ python write_to_scrapbox/main.py

Github
new repository omni
$ git remote add omni https://github.com/nishio/omni.git
$ git branch -M main
$ git push -u omni main

Cache File
$ cp ../../scrapbox_chatgpt_connector/nishio.pickle .
$ ls -l
-rw-r--r-- 1 nishio staff 588214717 Aug 8 23:53 nishio.pickle
% git lfs install
Updated Git hooks.
Git LFS initialized.
% git lfs track nishio.pickle
Tracking "nishio.pickle"
.gitignoreで*.pickleをignoreしてた
外した
:
% git push Uploading LFS objects: 100% (1/1), 588 MB | 7.2 MB/s, done. Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 10 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 463 bytes | 463.00 KiB/s, done. Total 4 (delta 1), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (1/1), completed with 1 local object. To https://github.com/nishio/omni.git 4e2f4a8..8800fb5 main -> main
secretsの設定
testを実行
Exporting a json file from "/undefined"
あれ?

あー、そうか、前回の修正を上流に返してないぞ
git push omoikane-embed-unnamed-project main をしたけど git push origin main してない
まあこれは僕が特殊なケース

おっと、指定したキャッシュファイルがかなり昔のものなのでフォーマットが違うな
:
Traceback (most recent call last): File "/home/runner/work/omni/omni/upload_vecs/main.py", line 86, in <module> main([f"{PROJECT_NAME}.pickle"], IS_LOCAL=False) File "/home/runner/work/omni/omni/upload_vecs/main.py", line 57, in main (payload["project"], payload["title"], payload["text"]) TypeError: string indices must be integers
最新版どこ…
% cp ../../qdrant/nishio-20230613.pickle nishio.pickle
% ls -l
-rw-r--r-- 1 nishio staff 735437681 Aug 9 00:19 nishio.pickle

ええー、新しいのにしてもダメだし、localで再現しないぞ?どういうことだ?

あー、これ
>それでダメだったら泥沼に入らないようにタイマーを回して調整しよう
のパターンでは?

あっ、わかった
古いキャッシュファイルを与えたことで、testでもそれを使ったpickleが作られた
ワークフローはこけてるけど、それより先にリリースへのアップロードは行われてるので不整合なpickleがアップロードされた
その後キャッシュを入れ替えたが「リリースがある場合にはリリースを優先」なので不整合データをベースに使われている
どうすべきか
テストの段階で型テストをして、不整合ならエラーになるべき
後のアップロードのフェーズでテストなのにキャッシュをまるごとアップロードしようとするのはおかしいので型テスト後にはレコードを削除する
不整合なキャッシュのリリースは削除する

Qdrantが負荷で接続できなくなってしまった
おかしいな、ずっとCPUが使いっぱなしだ
これは負荷ではなく、接続中にCtrl+Cしてクライアント側をしたが、サーバ側が接続を無限に待ち続けてて、そのせいで新しい接続ができなくなってるのかな
Qdrant側をリスタートする

動いた!

明日やること
omniの更新をcoreにpush
素朴にpushしようとしてLFSごとpushされそうになったから慌てて止めた
眠くない時に落ち着いてやる必要がある
解説を書く
unnamed-campの方でプロンプトをScrapboxから読むスタイルの実装をやる

2023/8/9
定期実行、全部2個こけてる
原因は全部 Uncaught (in promise) undefined when exporting a json file: Too many requests. Please retry later.
頻度という点ではテストを走らせてた時が多かったと思うから、これはどちらかというと全部同じタイミングでエクスポートを開始したのが問題か?

再実行
あっ、テスト用の小さいリリースを消し忘れて実行したから結局フルの処理が走ってしまった
そして50%進んだところで失敗した!
エラー時にスリープしてリトライするところにブレークポイントかけたままじゃん!
実質リトライなし
再再実行
できた
onmi
total tasks: 46426, 96.1% was cached processing 1797 tasks in 36 batches
ちゃんとcacheが効いてる

TODO
>omniの更新をcoreにpush
% git rebase -i origin/main
こうか
% git push -f omni main
で、ここからどうするんだ?
GPT4に聞いたらブランチ作りなと言われた
% git checkout b00a50d9fb8cac40f5567db4166f46bac1229ac3 -b common_develop
これをorigin/mainにどうpushするのか?
あ、このブランチをpushしてoriginの側でマージするのか、理解
% git push origin common_develop
Githubでプルリク作る?と聞かれた
うーん、これmerge以外の選択肢ないんだな
やめた

あっまた間違えた
こうして
% git checkout main
% git cherry-pick common_develop
こうかな
% git checkout common_develop
% git reset HEAD^
% git checkout .
% git push omni main
めでたしめでたし

unnamed-projectsの方を見る
現状、upstreamに返すべき特別な更新はない
スケジュールを変更しよう
箇条書きへの修正などは一旦手元の整理が終わって解説を書き終わってからにしよう
ローカルの名前がtmp/omoikane-embed-coreなんてのになってて後々困りそうなのでリネームする

えーと
ぐちゃぐちゃと試行錯誤したオリジナルのomoikane-embedを、他のプロジェクトに水平展開するために整理したのがomoikane-embed-core
えーと、これ、どう整理するのがいいのかな…
今のomoikane-embedをコピーしてアーカイブして、push -fしてしまうのがいいのかな
コピーして取っておくなんて機能はなかったw

とりあえず導入ガイドを先に書いた

ネクストアクション考えた
/unnamed-projectのボットを更新順ではなくランダムにする✅
このプロジェクト/omoikaneの定期処理自体もcoreから分岐して作る
将来的にプロンプトをScrapboxに置く

2023/8/10
success
success
は?
むしろ4時間走ったりできるんだ?すごいな
何が起きてるのか気になるがログが見れないな
でもまあ、止めるか
長時間待って、ちょっと動いて、また待ってる
なぜinitializingなのか

Github Actionsを止めてみた
RAMはむしろ上に張り付くな
それでHEALTHYになる
gptFree GitHub users have a limit of 2,000 minutes per month for GitHub-hosted runners.
無料枠は1ヶ月に33時間なので無限にリトライするのは良くない
あれ?0 minutesだな
>GitHub Actions usage is free for standard GitHub-hosted runners in public repositories, and for self-hosted runners. For private repositories, each GitHub account receives a certain amount of free minutes and storage for use with GitHub-hosted runners, depending on the account's plan. Any usage beyond the included amounts is controlled by spending limits.
public repositoryだから無料ということ?
リスタートして再開
ダメみたい
ローカルからやった時は行けたんだけどな

うーん、ローカルからやってもダメ
たくさんあるからダメなのではなく即座にダメ
つまり?今までギリギリ耐えていたけど今日の更新でomoikaneと unnamed-campを入れて、途中までnishioを入れたところで限界を迎えてそれ以降ダメになったということか?
新しく作れば日本リージョンにできる
スケールアップはアメリカのままだが、少し安い
んー
スケールアップで解決するのかも未知数だから作業量と金銭コストの両方安いスケールアップが正解か
SMS認証したらLinkとかいうサービスによってクレジットカード番号が入力された
なんだっけこれ…
まあいいか?
課金してRAM2GBにスケールアップしたということ?inajob

ダメだ、解決しないや
メモリを使い果たしたことで本格的に何かおかしくなってるのかな…
考えても仕方ないので作り直した
ついでに日本リージョンにして、コレクション名がtest-collection2だったのを直したw
差分upload commit
解決するかと思って実装したけど解決しなかった
とりあえず実行時間を減らすことにはなると思う
これが有効に機能するかはしばらく様子見
まとめ
再起動して検索に使う上では問題がない
Github Actionsでの追加時には600件くらい追加すると動かなくなるという振る舞いをしていた
多分OOM Killerで殺されて、インスタンスが死んだのを検知して再起動が走って、を繰り返している
過去の実験過程のデータとかを全部捨てて入れ直した
当面問題なく動くはず
たかだか2倍弱の余裕しかないはずなので、大規模に追加する実験をやるときにはまた死ぬだろう、事前にスケールアップしておく必要がある
ざっくり書籍100冊分くらいの分量で死ぬくらいの感じ

APIキーの書き換え
ローカルの.envだけでなくGithubもか
たくさんあるな…
omni
local✅
github✅
unnamed
local✅
github✅
omoikane
これはcoreをベースに作り直すからいいか
あっ、これそもそもURLがハードコードされてるじゃん
今日のうちに作り直さないと動かないな
vecsearch
omoikane✅
バグってそう?
Redeploy待ち
OK✅

nishio✅
あ、これもコレクション名を変えたから修正しないと動かないのか
Redeploy待ち
OK✅


omoikaneをcoreをベースに作り直す
できたはず
Github Actionsの結果確認待ち
NG
collectionをrecreateしてない
omoikane✅
unnamed-project✅
Github Actionsの結果確認待ち
OK✅
検索
OK✅

はー、なんとか直った。

定常状態のメモリ消費量より、レコード追加時の方が大きい
ここでOOM Killerが発動するのだろう
だから再起動後、検索に使うだけなら問題なく、追加をしようとすると少し走って死ぬ

課金してRAM2GBにスケールアップしたということ?inajob
後のスクリーンショットでRAM1GBと見えるから、作り直しただけ?
スケールアップで解決しようとしたが、解決できなかったのでDBが壊れてしまったなどの原因を考えて、というか他に手がないので、消して作り直したnishio
すべてのデータを入れ直してすべての設定を修正しないといけないからめんどくさかったw
どの程度でRAM1GBを消費するのか気になる
/nishioを入れ直した状態でこれ
RAMの青い輪が100%を超えても動いてるから「なんだ、大丈夫じゃん」と思って使い続けたら1.2〜1.3GBのあたりで今回のトラブルが発生して作り直す羽目になった
なので青いゲージが満タンになったら素直にスケールアップするのが良いと思う

mailきてた
I'd like to help out here if needed. We could offer you the following:
If you did not use memory mapped files yet, you can configure qdrant to put payload, index and more to disk and memmap it (might have a performance impact). Check our documentation here: https://qdrant.tech/documentation/storage/#vector-storage
If you can share some details on your use case I can probably also upgrade your RAM for free for a period of time till you are ready for production.
If you move to our regular paid standard tier clusters:
we can scale your cluster horizontally by adding nodes and shifting shards
we can also scale your cluster up vertically to the next higher package.
必要であればお手伝いしたいのですが。次のような提案ができます:
もしまだメモリマップファイルを使用していないのであれば、ペイロード、インデックス、その他をディスクに置き、memmapするようにqdrantを設定することができます(パフォーマンスに影響があるかもしれません)。https://qdrant.tech/documentation/storage/#vector-storage
もし使用例について詳細を教えていただければ、本番環境に移行するまでの期間、RAMを無料でアップグレードすることも可能です。
親切〜nishio
通常の有償スタンダード・ティア・クラスタに移行する場合:
ノードの追加やシャードの移動により、クラスタを水平方向にスケールアップできます。
また、お客様のクラスタを次の上位パッケージに垂直方向にスケールアップすることも可能です。
nishio
あー、なるほど、mmapするのか
今日はもう遅いので明日、3つのプロジェクトのデータが入ってる状態でディスクやメモリの状態を確認してから試そう

2023/8/11
/nishioを入れ直した状態でこれ

2023/8/12
nishio
上記Cの実験の結果、こうなった: AIとの共同化 /nishio/AIとの共同化
この二つの修正をこっちにも入れたいが、ちょっと疲れたな
3つのプロジェクトそれぞれでそれぞれのニーズに合わせてコンテンツ生成コードを書き換えてるので、どうやって良い変更を他のリポジトリに持っていったらいいかな?という気持ちになった

現状確認

キャッシュファイルがでかいから単純にoriginにpushするわけにはいかないよなあ、と思ってたんだが、むしろリリースを介したキャッシュが回り始めてるので消してもいいんじゃないかな?

あー、そうか、なるほど、coreの側でremoteを設定してfetchしcherry-pickか

まあでも自覚的に眠いので明日にしよう

環境が異なるとコードが違うの生物みたいだな

2023/8/13
今/nishioに入ってるものが一番有益だと思っている
しかしこれ自体もどんどん変えていきたい
/nishioに関しては毎日動いて良い、unnamedはそれでは頻度が高すぎるので「過去1日に更新がなければ」にしている
omoikaneもその方が良さそう
これらの組み合わせ…
まず「generate pages」という汎用的な名前なのがよくない
あー、そうか、わかった
A: omniに改良点が見えてて、それを直したい
B: omniは他のものより良いからそれを導入したい
これを同時にはできないんだ

Aをもりもり進めてJSONのエクスポートをせずに最新のノートの続きを書けるようなった
ワークフローが別物じゃん!

recurrent notes ver.1

unnamedに入れる
% git remote add omni https://github.com/nishio/omni.git
% git fetch omni
こうなる

% git checkout -b feature-from-omni
% git rebase -i --onto feature-from-omni HEAD omni/main

こうなった


omoikaneに入れる
% git remote add unnamed https://github.com/nishio/omoikane-embed-unnamed-project
% git fetch unnamed