Closed10

RAG とか Vector DB についてお勉強

Kota UENISHIKota UENISHI

元論文

Patrick Lewis, Ethan Perez, Aleksandra Piktus, Fabio Petroni, Vladimir Karpukhin, Naman Goyal, Heinrich Küttler, Mike Lewis, Wen-tau Yih, Tim Rocktäschel, Sebastian Riedel, and Douwe Kiela. 2020. Retrieval-augmented generation for knowledge-intensive NLP tasks. In Proceedings of the 34th International Conference on Neural Information Processing Systems (NIPS '20). Curran Associates Inc., Red Hook, NY, USA, Article 793, 9459–9474.

https://dl.acm.org/doi/abs/10.5555/3495724.3496517

わかりやすそうな記事

わかりやすそうな記事
https://blogs.nvidia.co.jp/2023/11/17/what-is-retrieval-augmented-generation/

わかりやすそうな記事
がぞう

https://www.nvidia.com/ja-jp/glossary/retrieval-augmented-generation/

Kota UENISHIKota UENISHI

現状なんとなくの理解

事前学習前・事後学習済のLLMはいろんなタスクをこなせるらしい。実際対話UIでHallucinationがあるにせよいろんな知識を持っている。いろんな試験に合格したとかそういうやつ。ただし input sequence ( "context" というらしい?) というかプロンプト以外の入力ができないので

  • モデルで事前に決まってるコンテキスト長(4k とかそういう)以上の入力ができない
  • LLMが覚えている知識を更新するには事後学習にかける以外の方法がなく、簡単に知識を追加する方法がない

という制約がある。これを解決するために RAG という技術をつかうと、Vector databaseに外部知識をたくわえていくと必要に応じてLLMの知識を増やすことができる。らしい。 Retrieval-Augmented Generation の略らしい。

Kota UENISHIKota UENISHI

基本構成の読解

むずかしい
とりあえず絵だけをはる

RAGの絵

GeneratorのほうはLLMじゃなくてBARTを使っている

Retriever (Pη) が出したTop-kのドキュメント候補に対して周辺確率を計算してスコアを計算することができるらしい。すごいな!
Sequence-modelとToken-modelの違いは∑してからΠするか逆か、の順番らしい

Kota UENISHIKota UENISHI

Retriever

DB屋やストレージ屋が興味あるのは、Retriever側でこれ

Retreiver

手習いなので数式を書き写すとこう

p_{\eta} (z|x) \propto exp( \textrm{d}(z)^{\textrm{T}} \textrm{q}(x) )

Where

\textrm{d}(z) = BERT_d(z), \textrm{q}(x) = BERT_q(x)

で、 d が decoder で q が(全部の)ドキュメントにスコアをつける君なので、この p_η が高いドキュメントを沢山引っ張ってくるのがVector databaseということになるっぽい

Kota UENISHIKota UENISHI

学習レシピ

ふつうに (x, y) でe2e で学習したとかいてある。学習中にへんなことはしていないらしい。
でも 2.4 Training に

keep the document encoder (and index) fixed, only fine-tuning the query encoder BERTq and the BART generator.

とも書いてあり、pretrainingではencoderがノータッチなのかよくわからなかった

Kota UENISHIKota UENISHI

NMSLib

FAISSの記事のなかでNMSLibが触れられていて Non-metric spaces で検索できるとかいている
Metric space (計量空間) は要は距離が定義される空間のこと。Metric spaces じゃないとSimilarityは定義できないと思うんだけど関係がよくわからない。

NMSLib が採用?しているHierarchical Navigable World graph (HNSW)だと確かに距離は関係ない気もする。

Kota UENISHIKota UENISHI

ANNS benchmarks

古くて新しい問題なのでベンチマークがある
https://github.com/erikbern/ann-benchmarks

オンメモリでデータセット固定っぽいので、いわゆる大規模とはすこし問題が違うっぽい

RAG Benchmark

これもググるといくつかある

論文(これはどこに出たんだろう?)

https://arxiv.org/abs/2407.11005

あんまり使われている感じはしない
https://ascii.jp/elem/000/004/214/4214552/
https://github.com/recursiveai/flow_benchmark_tools

CRAG

定番はこれっぽい(KDD Cup で使われたとのこと

https://github.com/facebookresearch/CRAG

NerlIPS24 に論文も出ている
https://arxiv.org/abs/2406.04744

Kota UENISHIKota UENISHI

この記事をみると、LangChainというツールキットがあり、そこにあるChromaというVector DBを使うのが鉄板らしい
https://dalab.jp/archives/journal/hybrid-search/

LangChain
https://zenn.dev/umi_mori/books/prompt-engineer/viewer/langchain_overview

LangChain Retrieval
https://zenn.dev/umi_mori/books/prompt-engineer/viewer/langchain_retrieval

Chroma DB

どうもこれが業界標準っぽいな

https://qiita.com/jingwora/items/d39635b2d727725bf4ca

https://ryuichi1208.hateblo.jp/entry/2024/09/10/150208

https://qiita.com/kenichiro_nishioka/items/9f578cc670264d8fdf6b

https://github.com/chroma-core/chroma

Official doc
https://docs.trychroma.com/
Chroma Cloudというやつもあるらしい

バックエンドはRedisがデフォルト?っぽいと思ったがソースコードをみるとSQLiteバックエンドのコードがあるのでそれじゃないか?という気はしている。それとは別にNNSは結局NSWLibの縮小版 HNSWLib を使っているらしく、NNSとDBスキーマの関係は気になる。
あとそれっぽいProtobufのファイルもあったのでこのあたりを理解すると理解が深まりそう。

それとは別にChromaとLLMをどう組み合わせるかも調べてみたほうがよさそう(あんまりいいサンプルが落ちてない)
結局MSのサンプル が一番わかりやすくてイメージわくので転載しておく

user_input = "what is a perceptron?"

def chatbot(user_input):
    # Convert the question to a query vector
    query_vector = create_embeddings(user_input)

    # Find the most similar documents
    distances, indices = nbrs.kneighbors([query_vector])

    # add documents to query  to provide context
    history = []
    for index in indices[0]:
        history.append(flattened_df['chunks'].iloc[index])

    # combine the history and the user input
    history.append(user_input)

    # create a message object
    messages=[
        {"role": "system", "content": "You are an AI assistant that helps with AI questions."},
        {"role": "user", "content": history[-1]}
    ]

    # use chat completion to generate a response
    response = openai.chat.completions.create(
        model="gpt-4",
        temperature=0.7,
        max_tokens=800,
        messages=messages
    )

    return response.choices[0].message

chatbot(user_input)
このスクラップは21日前にクローズされました