2023-03-01 LlamaIndexのコードを読む
LlamaIndexのコードを読む

LlamaIndexのNodeの単位をどうやって制御するのか

これは単にファイルを読んでDocumentを返してるだけ
これは文字列のリストを個別にDocumentにしてる
トークン数を数えるのにはこれを使ってる
tiktoken.get_encoding("gpt2")
GPT2から変わってないのか
Yes
GPTIndexを作る際に勝手にドキュメントを結合してしまう?
DocumentStoreの中身が1個になっちゃう?
ノードが分かれてるからちゃんとそのノードだけ読むようだ
断片にインデックスをつけるのができるようになった
クオリアさんの過去発言データを整備すれば...
def get_queued_text_embeddings(self) -> Tuple[List[str], List[List[float]]]:
OpenAIEmbedding#get_embedding
この辺が最終的に呼ばれるのだろう
GPTVectorStoreIndex
BaseGPTIndex
ここで OpenAIEmbedding
default: "text-embedding-ada-002"
そうなのか〜
- OpenAIEmbeddingMode.SIMILARITY_MODE
- OpenAIEmbeddingMode.TEXT_SEARCH_MODE
TEXT_SEARCH_MODEがdefault
self.build_index_from_documents(documents)
が呼ばれる
そこの先は _build_index_from_documents
が @abstractmethod
で子クラスに戻る
self._use_async
default: Falseなので
pyfor d in documents:
self._add_document_to_index(index_struct, d)
self._get_node_embedding_results(...)
pydef _get_node_embedding_results(
self, nodes: List[Node], existing_node_ids: Set, doc_id: str
) -> List[NodeEmbeddingResult]:
各nodeのtextをqueueに入れてから
result_ids, result_embeddings = self._embed_model.get_queued_text_embeddings()
ここで OpenAIEmbedding
に処理が移る
おっと違った BaseEmbedding
の get_queued_text_embeddings
だ
これが embeddings = self._get_text_embeddings(cur_batch_texts)
する
で、もちろん _get_text_embeddings
が OpenAIEmbedding
でオーバーライドされてるわけだ
だいぶ著者の気持ちが読めるようになってきたw
OpenAIEmbedding#_get_text_embeddings
embeddings = get_embeddings(texts, engine=engine)
get_embeddings
の中でOpenAIを呼んでる
data = openai.Embedding.create(input=list_of_text, engine=engine).data
index.query
BaseGPTIndex#query
return query_runner.query(query_str, self._index_struct)
/gpt_index/indices/query/query_runner.py
return query_obj.query(query_bundle)
/gpt_index/indices/query/base.py
BaseGPTIndexQuery
def _query(self, query_bundle: QueryBundle) -> Response:
tuples = self.get_nodes_and_similarities_for_response(query_bundle)
ここで類似度に基づく検索をしている
[(Node(text='56: Have Presence of Mind.\n...', doc_id='a8e898fd-...', embedding=None, extra_info=None, index=0, child_indices=set(), ref_doc_id='a51e3fc7-...', node_info={'start': 0, 'end': 602}), 0.800589425093737)]
text, response = self._get_text_from_node(query_bundle, node)
なぜ _get_text_from_node
が response
を返す?
recursiveのとき、リクエストを発行することがあるから
今回の場合はしないのでNoneが返る
response_str = self._give_response_for_nodes(query_bundle.query_str)
response = self.response_builder.get_response(...)
ResponseBuilder
give_response_single
2023-03-05

GPTVectorStoreIndexQuery
の _get_nodes_for_response
で query_result = self._vector_store.query(query_embedding, self._similarity_top_k)
してる
SimpleVectorStore#query
がユーティリティ関数 get_top_k_embeddings
を呼び出してる
この中で、全部類似度を計算して、ソートしてK個取ったものを返してる
つまり「ベクトルサーチの結果をトークン上限Xで返させる」オプションはない
2023-03-07
デフォルトはコサイン類似度
def similarity(
>OpenAI embeddings are normalized to length 1, which means that: doc
区別する意味ないな
LlamaIndexもFAISSを使うことができそう
def load_from_disk(
デフォルトはJSON