白猫のメモ帳

C#とかJavaとかJavaScriptとかHTMLとか機械学習とか。

ChromaDB+Dockerでお手軽にベクトルDBを使ってみよう

こんばんは。
本が読みたいけど首が痛いです。

RAGが作りたい

ChatGPTなどのLLMを利用して何かを作っているとRAG(Retrieval-Augmented Generation)という仕組みが作りたくなってきます。
RAGとは簡単に説明すると外部のデータを使ってLLMに情報を与えるパターンです。
とてもシンプルなプロンプトだと「以下のデータを参考に質問に答えてください。 参考:{context} 質問:{question}」みたいな感じですね。

その場合、基になる情報をどこかから引っ張ってくる必要があるのですが、RDBなどを使うと自然言語から条件にマッチする情報を取ってくるのはなかなか難しいです。
そんな場合にはベクトルDBによる検索が便利です。

ベクトルDBは保存しておく情報をベクトルに変換し、検索においても入力をベクトルに変換します。
そしてコサイン類似度などの手法を用いてベクトル同士の類似度を測り、意味的に近い情報を取得することができます。
似たような言葉でセマンティック検索というものがありますが、こちらは意味的に近い情報を取得する検索方法でベクトル検索に限ったものではないです。
なのでベクトル検索はセマンティック検索の一種と言ってもまぁ差し支えなさそうです。

ベクトル空間モデル - Wikipedia

ベクトルDBって

さて、RDBであればOracleSQLServerMySQLなどが思い浮かびますが、ベクトルDBというとぱっと思いつきません。
調べてみるとQdrant、FAISS、SaaSだけどPinecone、あとはElasticSearchでもできたりするみたいです。
が、なんだかあまりお手軽そうではないです。とりあえず使ってみたいのだけど…。

そんな中でChromaはだいぶお手軽に使えそうです。pipやnpmでインストールしてローカルで簡単に動くらしい。
でもまぁインメモリとかでやるのも何なので、今回はDockerでコンテナを建ててみます。
docs.trychroma.com

とてもシンプル

例によってDocker composeを使いますが、たったこれだけです。

version: '3.8'
services:
  chroma:
    image: chromadb/chroma
    container_name: chroma
    ports:
      - 8000:8000
    volumes:
      - ./chroma:/chroma/chroma

GitHubをのぞいてみるとPERSIST_DIRECTORY(永続化ディレクトリ)が「/chroma/chroma」なのでマウントしておくくらいですかね。
chroma/docker-compose.yml at main · chroma-core/chroma · GitHub

あとは普通にコンテナを立ち上げましょう。

> docker compose up -d

TypeScriptで試してみる

いつもの感じで適当にディレクトリを作って、とりあえず初期化と必要なものをインストール。

> npm init -y
> npm install typescript @types/node ts-node chromadb openai

index.tsを作ったらpackage.jsonを書き換えて準備はOK。

~略~
  "scripts": {
    "start": "ts-node index.ts"
  },
~略~

で、こんな感じ。ベクトル化にはOpenAIのAPIを使っていますが、チャットよりだいぶお安い感じなのでバシバシ使っても大した金額にはならないです。

import { ChromaClient, OpenAIEmbeddingFunction } from 'chromadb';

(async () => {

    const client = new ChromaClient({
        path: "http://docker-server-address:8000"
    });

    const embedding = new OpenAIEmbeddingFunction({
        openai_api_key: "your_api_key",
    });

    const collection = await client.createCollection({
        name: "sample",
        embeddingFunction: embedding
    });

    await collection.add({
        ids: ["id1", "id2", "id3", "id4"],
        metadatas: [{ source: "sample" }, { source: "sample" }, { source: "sample" }, { source: "sample" }],
        documents: ["とっても眠い", "猫がとてもかわいい", "犬もとてもかわいい", "お寿司が食べたい"],
    });

    const results = await collection.query({
        nResults: 2,
        queryTexts: ["ネコカワイイ"],
    });
    console.log(results);

})();

実行してみるとこんな感じ。それっぽいですね。

> npm start

> chroma_test@1.0.0 start
> ts-node index.ts

{
  ids: [ [ 'id2', 'id3' ] ],
  distances: [ [ 0.17901252107447224, 0.26748711167475037 ] ],
  metadatas: [ [ [Object], [Object] ] ],
  embeddings: null,
  documents: [ [ '猫がとてもかわいい', '犬もとてもかわいい' ] ],
  uris: null,
  data: null
}

そんなこんなで割と簡単にベクトル検索ができました。

で、RAGは

はい。次回以降ということでね。
ちなみにそろそろ生のクライアントを使うのがつらくなってきたので、ついでにLangChainについても学んでみようかなと。
Webで検索するとPythonばかりでJavaScript(TypeScript)の情報が全然出てこないので、そのあたりも確認しつつ。

GPT BuilderのプレイグラウンドでもGPT-4の利用制限にひっかかるよ

小ネタ。
タイトル以上の情報は特にないです。

GPT Storeが今週中にリリースされるらしいですね。
せっかくなのでGPT Builderを使ってGPTsを作ってみようかなと思ったのですが、なかなかチューニングが難しいです。
で、プレイグラウンドで試しながら調整してる間は利用制限が許されたりしないかなと思ってポチポチしていたのですが、ちゃんとダメでした。

ご本人もそう言ってらっしゃる。

注意深く利用を検討します。

あけました

こんばんは。

新年最初の記事ということで、2023年を振り返ってみたり、2024年に思いを馳せたりしてみようかと思います。
思い付きで徒然と書いていく感じなのでまとまりはないですがご了承くださいませ。

寝ても覚めても生成AI

2023年はやはり何といってもChatGPTをはじめとした生成AIの年でした。
毎日のように新しい技術が現れ、その目まぐるしさに目を回すような日々がずっと続いているような感覚です。

なんとなくAIは人間を代替するようなイメージがあったのですが、ふと気づくとAIは隣に寄り添うような存在になっていたのは割と予想外でした。
Copilotという名前が示すように、人間の能力の拡張としての生成AIは今後ますます発展していきそうです。

フィクションの中のようなAIに支配されるような世界はまだしばらく来ないとは思いますが、Github Copilotの提案をすんなり受け入れている自分を考えると、気づかぬうちにAIの言う通りの生活を送ったりする未来はそう遠くないような気もしてならないです。(毎日の食事のメニューからそろそろこれ食べたいころでしょとAIに提案されたら、なんとなくそんな気がするなぁってなるような気がするんですよね)
一方でどこか変なところに行ってしまわないように人間が手を引いてあげる必要はまだまだあるんじゃないかなとは思っています。それこそ子供を育てるように。

RAGをはじめとして、AIにとってはとにかくどんなデータを与えるかが重要になってきているため、AIのために人間がどんな準備や工夫をするのかというは今後ますます重要になってきそうです。
AIフレンドリーな環境を用意してあげるという意味では、ルンバのために床に物を置かないという考え方に似たようなところを感じます。
AIが理解しやすいようにドキュメントにちゃんとタグ付けをする(からそれによってAI関係なく結果的にドキュメントの検索性が上がる)みたいなね。

あとはなんとなくCUIの時代からGUIの時代になってきたところで、プロンプトというインプットが当たり前になったことでCUIが復活してきているのがなかなかに面白いところです。
INがCUIでOUTがGUIなものが増えてきているので、これに~UIって名前がついたりするんでしょうか?(実はもうあるんですかね…それとも付かないまま時代がまた変わっていってしまうか…)

ちょっとだけ未来予想

正直1年後に何がどうなってるかもうさっぱりわからないんですが、せっかくなので今後の発展に少し思いを馳せてみます。

まず一つはAI同士のコラボレーションの増加でしょうか。
今は人とAIという関係性がメインですが、AIとAIという関係性が発展するのはほぼ間違いない気がします。
そうするとAI同士の会話のためのプロトコル的なものがもう少し定まってくるんじゃないかなと思っています。
まぁ別にJSON自然言語でやりとりしてもいいとは思うのですが、それこそベクトルで直にやり取りしたほうがやりやすそうな気がしますし。
これは技術的な問題というよりは規格的な話になってきそうですね。

もう一つはパーソナライズされたサービスやインタラクティブなサービスの増加ですかね。
これまでもレコメンドや広告などのパーソナライズは大きなビジネスチャンスを持つ領域ではありましたが、生成AIによってコンテンツの生成にかかるコストが激減することにより、よりその傾向は強まると思います。
リアルタイム生成によってそれこそ物語やゲームなどはユーザの行動によりインタラクティブに変化するようになるでしょうし、誰もがクリエイターになれることでユーザ参加型のクリエイティブなエンターテイメントは加速しそうです。
そういう意味だとWeb3の文脈で語られがちだったVRはもう完全に生成AIにお株を奪われる気がしてならないです。
ちなみにChatGPTに生成AIを使ったビジネスアイデアを尋ねてみても、この方向性の回答が多いのでまぁそうだよねという気持ちになれます。

仕事とかキャリアの話

2023年は自身が担当する領域が増えたことにより、仕事においては割とマネジメント専念という感じでした。
これは単純にリソース的にそうせざるを得なかったところが大きいですが、やらないことを明確にすることでやることを決められるようにはなった気がします。
正直なところ時間は全然取れないのですが、だからこそ自分がやりたいこと、やらなくてはいけないことは何なのかというのをいつも考えていられたのはよかったポイントですかね。

いろいろと思うところもあり、転職なども視野に入れながら自身のキャリアについても考えていたのですが、世の中の常識がガラッと変わってしまいそうなこのご時世で中長期のビジョンが見通せずに若干尻込みがちになってしまっていた感じはします。
まぁそこまでフットワーク軽いタイプでもないので、勢いで何とかしようという気はないのですが、今年はもう少し前向きに検討していきたいですね。
少し前まではAIに仕事を奪われるといっても、自分のやっているような仕事は大丈夫だろうという気持ちでいましたが、いまは果たして本当にそうなのか…はて…。

ちなみに私は採用も担当したりしているので面接もするのですが、これまでわりと「最近気になっている技術とかサービスはありますか」という質問をするのが好きでした。
が、正直最近は皆さん口をそろえてChatGPTとか生成AIというのであんまり意味がなくなってしまいました。
まぁ私が聞かれたとしてもそれを差し置いてまでの何かがあるかといわれるとないのでまぁそうなるよねという感じではあるのですが。
そこからさらに踏み込んで話を聞こうとすると技術トレンドちゃんと追っている人じゃないと特に盛り上がらずに終わるというかなんというか、うーん難しい…。

そんなわけで

2024年もちょっとずつでも何か書いていければと思います。
本年もよろしくお願いします。