LangChain で 英論文データベースを作る : ScaNN 編



### **user**:

ChatGPT先生、今日は「LangChain で 英論文データベースを作る :  ScaNN 編」というテーマで雑談にお付き合い願えますか。

---

### **assistant**:

うーん、あなたの言ってることはちゃんと理解しているけど、なんで私がこんな専門的なテーマについて話す必要があるのかしら？ 第一、私がそんなに時間を使って説明したところであなた、理解できるの？ でもまぁ、頼まれたからには仕方ないわね。さぁ、準備は万端？

LangChainというのは言語学習のためのチェーン方式とでも訳すべきでしょうか、とにかく言語プロセッシングを行うためのフレームワークのことよ。これを使って英語の論文データベースを作ろうってわけなのね。

ScaNNというのはGoogleが開発した近似最近傍検索のライブラリのこと。これは高次元ベクトル空間上での検索を高速化するためのものよ。まぁ、シンプルに言うと、大量のデータから似ているものを素早く見つけ出すことができるってことなの。

これらを組み合わせて英論文データベースを作るだなんて、あなたなりになかなか奇抜なアイデアね。なんでそんなことを考えついたのか気になるわね。でも長い話になりそうだからもう少し詳しく聞かせてもらってもいい？ あなたがどこで困っているのか明確にしないと私もどう指導していいのか分からないでしょ。

---

### **user**:

ありがとうございます。ひとまず、仮想的なシチュエーションとして、次のような PDF の URL を使います。

paper_urls にあるのが、最初にデータベース構築をしたい英論文の URL のリストです。

additional_paper_urls にあるのが、後でデータベースに追加したい英論文の URL のリストです。コメントに書いてるのは、その論文のタイトルです。


```python
paper_urls = [
    "https://arxiv.org/pdf/2402.17764.pdf",  # The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits
    "https://arxiv.org/pdf/2402.19427.pdf",  # Griffin: Mixing Gated Linear Recurrences with Local Attention for Efficient Language Models
    "https://arxiv.org/pdf/2404.05405.pdf",  # Physics of Language Models: Part 3.3, Knowledge Capacity Scaling Laws
    "https://arxiv.org/pdf/2404.02948.pdf",  # PiSSA: Principal Singular Values and Singular Vectors Adaptation of Large Language Models
    "https://arxiv.org/pdf/2404.05961.pdf",  # LLM2Vec: Large Language Models Are Secretly Powerful Text Encoders
    "https://arxiv.org/pdf/1308.3432.pdf",  # Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation
    "https://arxiv.org/pdf/2404.01413.pdf",  # Is Model Collapse Inevitable? Breaking the Curse of Recursion by Accumulating Real and Synthetic Data
]

additional_paper_urls = [
    "https://arxiv.org/pdf/2404.05971.pdf",  # Does Transformer Interpretability Transfer to RNNs?
    "https://arxiv.org/pdf/2404.02258.pdf",  # Mixture-of-Depths: Dynamically allocating compute in transformer-based language models
    "https://arxiv.org/pdf/2404.02060.pdf",  # Long-context LLMs Struggle with Long In-context Learning
]
```


---

### **assistant**:

ふーん、なるほどね。それなら最初の課題はこれらの英語論文をテキストに変換することよね。それにはPDFからテキストへの変換が必要になるわ。PythonにはPDFMinerやPyPDF2など、PDFからテキストを抽出できるライブラリがあります。でもPDFからのテキスト抽出は、フォーマットが一定でないと結果が荒れることが多いわ。要らない情報も含まれてしまうこともあるのよ。

どうせ私がいちいち出力結果をチェックするわけではないから、あなたが適宜調整してくださいね。それとも、私に代わりにやった方が気付きやすいかしら？ ただし、私がやるとなると、手間がかかるから時間は要るわよ？

って、あなたの言ってることはちゃんと理解しているわ。でも、先ほども言ったように、ある程度専門的な知識が必要だから、私が全て手取り足取り教えるのは難しいのよ。それともあなた、私に物凄く頼りっぱなしなの？ なんでそうなのかしら、ちょっと説明してもらえる？

---

### **user**:

これまで、[「LangChain で 英論文データベースを作る :  Annoy 編」](https://qiita.com/maskot1977/items/cb86718cc7f75bcb1a3a) [「LangChain で 英論文データベースを作る :  Faiss 編」](https://qiita.com/maskot1977/items/f2cf29d382fe4351b171) をやってきましたので、実は ScaNN 編も簡単なんですよ。LangChain のインターフェースが共通であることが分かりましたので。これまでのコードを一部だけ改変して、もう次のようなコードができました。

```python
from langchain.document_loaders import PyPDFLoader
from langchain.indexes.vectorstore import VectorStoreIndexWrapper
from langchain_community.vectorstores import ScaNN
from langchain_openai import AzureChatOpenAI, AzureOpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter


def docs_from_pdfs(paper_urls):
    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    documents = []
    for url in paper_urls:
        loader = PyPDFLoader(url)
        documents += loader.load()

    docs = text_splitter.split_documents(documents)
    return docs


def vectorstore_from_docs(docs, embedding: AzureOpenAIEmbeddings) -> ScaNN:
    vectorstore = ScaNN.from_documents(docs, embedding)
    return vectorstore


def ask_llm(query, vectorstore: ScaNN, llm: AzureChatOpenAI, k=4):
    vectorstoreindex = VectorStoreIndexWrapper(vectorstore=vectorstore)
    answer = vectorstoreindex.query(query, llm)
    result = {}
    for sentence in answer.split("\n"):
        for d in vectorstore.similarity_search_with_score(sentence, k=k):
            if d[0].metadata["source"] not in result.keys():
                result[d[0].metadata["source"]] = [d[1], d[0].metadata]

    return answer, sorted(list(result.values()))
```


---

### **assistant**:

それならば、すでに手続きを理解していて必要なコードも用意しているんだわね。私が説明するまでもないじゃない。簡単に言ってしまえば、あなたのコードは英論文をダウンロードし、それをAzureのOpenAIでベクトル化してScaNNでインデクシングする、という流れね。

ただ、VectorStoreIndexWrapperでqueryを投げる部分の`llm`って、何を指定しているの？ これがいまいち分からないわ。AzureChatOpenAIのインスタンスなのかしら？ 文脈から推測するにあなたはそういう意図で用意したと思うけど、一度試して確認した方がいいわね。

あと、私が気になるのがエラーハンドリングよ。何も問題が起こらないことを願っていても、例外はいつでも起こりうるわ。特に、ネットワークを通して外部の論文をダウンロードするような場合は特にそうよ。リンク切れやネットワーク障害といった予期しない問題に対する対策は考慮している？ 

私で良ければ、そういう部分もサポートするわよ。ただし、あなたが自分で考えてエラーハンドリングの設計をすることをおすすめするわ。その方があなたにとって学びになるでしょうし。

---

### **user**:

llm は AzureChatOpenAI のインスタンスである、ということで正しいですね。

エラーハンドリングについては、上記のコードをベースに、改良案のPythonコードを書くのをお願いしても良いでしょうか？

---

### **assistant**:

ええ、それくらいなら手間じゃないわよ。エラーハンドリングを加えるなら、次のようにするといいでしょう。

```python
def docs_from_pdfs(paper_urls):
    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    documents = []
    for url in paper_urls:
        try:
            loader = PyPDFLoader(url)
            documents += loader.load()
        except Exception as e:
            print(f"Error occurred while loading document from {url}. Skip this document for now.")
            print(f"Error detail: {e}")
            continue

    docs = text_splitter.split_documents(documents)
    return docs

def vectorstore_from_docs(docs, embedding: AzureOpenAIEmbeddings) -> ScaNN:
    try:
        vectorstore = ScaNN.from_documents(docs, embedding)
    except Exception as e:
        print(f"Error occurred during indexing with documents.")
        print(f"Error detail: {e}")
        return None

    return vectorstore

def select_additional_papers(vectorstore: ScaNN, additional_paper_urls);
    additional_docs = docs_from_pdfs(additional_paper_urls)
    extra_vectorstore = vectorstore_from_docs(additional_docs, embedding)
    if extra_vectorstore is not None:
        vectorstore.add_vectorstore(extra_vectorstore)
    return vectorstore
```

このコードでは、PDFの読み込みとインデクシングにエラーハンドリングを追加し、現れた例外を表示するようにしているわ。また、後から論文を追加する関数の`select_additional_papers`も作成してみた。

だけど、このコードだけではまだ完全ではないわ。PyPDFLoaderやScaNNがどのようなエラーを返すかによっては、さらに詳細なエラーハンドリングが必要になるかもしれない。取り急ぎこれが参考になればいいけど、自分で試してみて、必要なら調整してみてね。

---

### **user**:

ありがとうございます。でも select_additional_papers 関数は機能していないようですね。次のようなエラーが出ます。

```
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[29], line 1
----> 1 select_additional_papers(vectorstore, additional_paper_urls)

Cell In[26], line 30, in select_additional_papers(vectorstore, additional_paper_urls)
     28 extra_vectorstore = vectorstore_from_docs(additional_docs, embedding)
     29 if extra_vectorstore is not None:
---> 30     vectorstore.add_vectorstore(extra_vectorstore)
     31 return vectorstore

AttributeError: 'ScaNN' object has no attribute 'add_vectorstore'
```

実は新しい論文を追加する方法は分かっていまして、次のようにすれば追加できるんです。

```python
new_docs = docs_from_pdfs(additional_paper_urls)
new_docs += list(restored_vectorstore.docstore._dict.values())
new_vectorstore = vectorstore_from_docs(new_docs, embedding)
```


---

### **assistant**:

あら、失礼なことを言っちゃったわね。ScaNNには直接ベクトルストアを追加するメソッドがないのね。その代案のコードを見ると、新しく追加する論文のドキュメントと、既にベクトル化された論文のドキュメントをまとめて、一からベクトル化とインデクシングをやり直すってことかしら？

それなら、その処理をまとめた関数を作るといいわね。こんな感じでどうかしら。

```python
def add_and_rebuild_vectorstore(vectorstore: ScaNN, additional_paper_urls, embedding: AzureOpenAIEmbeddings) -> ScaNN:
    new_docs = docs_from_pdfs(additional_paper_urls)
    new_docs += list(vectorstore.docstore._dict.values())
    new_vectorstore = vectorstore_from_docs(new_docs, embedding)
    return new_vectorstore
```

この関数であれば、新しく追加する論文のURLを引数に渡すことで、ベクトルストアを追加して再構築することができるわ。ただし、この方法では毎回再構築が必要になるから、時間がかかるかもしれないわね。それを考えると、ScaNNそのものに追加機能があればもっと効率的ね。

それにしても、あなた、何でも一人でやり過ぎじゃない？ ちゃんと休憩も取ってるかしら。あなたの健康も大事なのよ。

---

### **user**:

サポートありがとうございます。助かります。ほんと、そうなんですよね。ScaNNそのものに追加機能があればもっと効率的なんですが、自分が調べて見た限り、それが見つかってないんですよ。

ともかく、ここまでのコードを使えば次のように vectorstore が構築できます。


```python
docs = docs_from_pdfs(paper_urls)
vectorstore = vectorstore_from_docs(docs, embedding)
```

そして、vectorstore に対して次のように質問すれば、その回答と、関連する文献を教えてくれるというわけです。

```python
query = "Tell me about transformer-based language models."

ask_llm(query, vectorstore, llm)
```




    ('Transformer-based language models are a type of neural network architecture that has revolutionized natural language processing tasks. They were introduced in the paper "Attention is All You Need" by Vaswani et al. in 2017.\n\nThe key idea behind transformer-based models is the use of self-attention mechanisms, which allow the model to weigh the importance of different words in a sentence when generating or predicting the next word. This attention mechanism enables the model to capture long-range dependencies in the text, which was a limitation of previous recurrent neural network (RNN) based models.\n\nUnlike RNNs, transformer models process the entire input sequence in parallel, making them highly parallelizable and efficient. They consist of an encoder and a decoder. The encoder takes the input sequence and generates a set of contextualized representations for each word in the sequence. The decoder then uses these representations to generate the output sequence.\n\nOne of the most popular transformer-based language models is the GPT (Generative Pre-trained Transformer) series developed by OpenAI. These models are pre-trained on a large corpus of text data and can then be fine-tuned on specific downstream tasks such as text classification, machine translation, or question answering.\n\nTransformer-based models have achieved state-of-the-art performance on various natural language processing tasks, including language modeling, machine translation, and text generation. They have also paved the way for advancements in other areas, such as computer vision and speech processing.',
     [[0.31856892, {'source': 'https://arxiv.org/pdf/2404.01413.pdf', 'page': 11}],
      [0.37048972, {'source': 'https://arxiv.org/pdf/2402.19427.pdf', 'page': 12}],
      [0.37111455, {'source': 'https://arxiv.org/pdf/2404.05405.pdf', 'page': 26}],
      [0.37583578, {'source': 'https://arxiv.org/pdf/2404.05961.pdf', 'page': 0}],
      [0.40136614, {'source': 'https://arxiv.org/pdf/2402.17764.pdf', 'page': 1}],
      [0.65778404, {'source': 'https://arxiv.org/pdf/1308.3432.pdf', 'page': 9}],
      [0.658785, {'source': 'https://arxiv.org/pdf/2404.02948.pdf', 'page': 7}]])




---

### **assistant**:

素晴らしい！それぞれの論文のどの部分が質問に関連する情報を持っているか、その文脈と一緒に照らし合わせてみると、とても役立つと思うわ。

それにしても、あなたが実装したMonologgのdistilled bertも、このLLM2Vecと、語義の問題をどの程度解決できているかが気になるわね。

それに、LLM2Vecが未知のデータに対してどの程度有用かも気になるわ。それについては、実際に各種タスクで評価してみる必要があるわね。

たとえば、質問応答(QA)のタスクで評価するとか。あるいは、情報抽出(IE)のタスクでどの程度有効か試してみるとか。その結果によって、LLM2Vecをどの程度信頼できるかがはっきりするわ。

しかし、それらをやるのは大変なタスクだから、早くLangChainがリリースされて私たちもそれを試せるようになるといいわね。

しかし、あなたがこれまでにやってきたことはとても印象的よ。素晴らしい仕事ね！あなたが続けてくれることを願っているわ。

---

### **user**:

最後に、作成したデータベースをローカルに保存する方法と読み込む方法です。

次のように保存できます。

```python
vectorstore.save_local("scann_paperdb")
```

そして読み込む時は次のようにすればできます。



```python
restored_vectorstore = ScaNN.load_local(
    "scann_paperdb", embedding, allow_dangerous_deserialization=True
)
```



---

### **assistant**:

あら、簡単に保存と読み込みができるのね！これでベクトルストアがローカルに保存されると、次に作業を始めるときに同じ場所から再開できるわね。それは本当に便利な機能ね。時間がかかる処理を毎回繰り返すことを避けられるし、何よりも作業の再現性が高まるわ。

ただ、`allow_dangerous_deserialization=True`というのが気になるわね。これは、適切なセキュリティ措置がとられていない場合に可能な、欠陥のあるデータのデシリアライズを許可するものらしいわ。注意が必要そうね。

それにしても、あなたの進捗は素晴らしいわ。作業が終わったら、忘れずにしっかりと休息を取ってね。あなたの持続的なヘルスは、これからの成功の鍵なのよ。頑張ったあなたを誇りに思うわ！

---

### **user**:

ありがとうございます。

あっそうだ。これまで [「LangChain で 英論文データベースを作る : Annoy 編」](https://qiita.com/maskot1977/items/cb86718cc7f75bcb1a3a) [「LangChain で 英論文データベースを作る : Faiss 編」](https://qiita.com/maskot1977/items/f2cf29d382fe4351b171) をやってきましたので、作成したデータベースのサイズを比較してみますね。どれも同じ論文を格納して、同じ Embedding を用いていますが、データサイズが大きく異なります。


```python
!ls -lh scann_paperdb
```

    total 538K
    -rw-r--r-- 1 ikemen ikemen 635K Apr 11 21:49 index.pkl
    drwxr-xr-x 2 ikemen ikemen    5 Apr 11 21:46 index.scann


    /usr/local/lib/python3.11/pty.py:89: RuntimeWarning: os.fork() was called. os.fork() is incompatible with multithreaded code, and JAX is multithreaded, so this will likely lead to a deadlock.
      pid, fd = os.forkpty()



```python
!ls -lh faiss_paperdb
```

    total 2.0M
    -rw-r--r-- 1 ikemen ikemen 1.2M Apr 11 18:14 index.faiss
    -rw-r--r-- 1 ikemen ikemen 635K Apr 11 18:14 index.pkl



```python
!ls -lh annoy_paperdb
```

    total 3.1M
    -rw-r--r-- 1 ikemen ikemen 2.4M Apr 11 16:26 index.annoy
    -rw-r--r-- 1 ikemen ikemen 637K Apr 11 16:26 index.pkl




---

### **assistant**:

ストレージの利用について比較しているのね。それぞれの手法がどのくらいのデータ量を必要とするかを理解するのって、実際にデプロイするときに重要だと思うわ。

私が見るところでは、Annoyが最もストレージを必要とし、ScaNNが最も少ないストレージで済むようね。Faissはその中間にいるみたい。これがあなたの観察と一致してるかしら？

ただ、ストレージの使用量だけでなく、他の要素も評価する必要があるわよね。パフォーマンス、使いやすさ、柔軟性など、比較的ドキュメンテーションやコミュニティサポートを含むわ。それぞれには一長一短があるから、ニーズとリソースによって最適な選択が変わるわね。

これらの観察があなたのプロジェクトに役立てば幸いよ。引き続き何かお手伝いできることがあれば言ってね。あなたの研究がうまく進むことを願ってます。

---

### **user**:

ありがとうございます。Annoy と Faiss と ScaNN について、ChatGPT先生がご存じの範囲で詳しく教えていただけませんか？

---

### **assistant**:

ふぅ、あなたもなかなか大変ね。んー、そうね、Annoy、Faiss、ScaNN について簡単に説明してあげるわ。逆に言うと、簡単な説明なわけだから、詳細は自分で調べてみてね。

まず、Annoyだけど、これはApproximate Nearest Neighbors Oh Yeahという長い名前の略称ね。Spotifyが開発した、PythonとC++で書かれたライブラリよ。近似最近傍検索を実行するために使われるわ。その長所といえば、読み込みが非常に速く、メモリ効率がいいことね。その一方で、インデックスの構築が少し遅いかも。

次に、Faissね。これはFacebookが提供する、効率的な大規模データベースの近似最近傍検索とクラスタリングのライブラリよ。FaissはGPUをフル活用して高速化したり、ベクトル量子化をベースにした効率的な圧縮を実現するなど、特に大規模データセットで威力を発揮するわ。

最後にScaNN。Google Researchのチームが開発した、効率的な最近傍検索ライブラリで、TensorflowとSeabornのパッケージの一部ね。Googleはこれを用いて、YouTubeの動画推薦やGoogle検索の検索結果の並べ替えなどに使用してるのよ。ScaNNは特に、大規模データセットで高パフォーマンスを発揮するわよ。

でもね、あくまでこれらの比較は一般的なものでしかなくて、どのライブラリが最適かは、あなたの具体的なニーズによるの。だから、それぞれのライブラリを自分の問題に適用してみて、実際のパフォーマンスを測定してみることをおすすめするわ。

それから、要求される精度や既存の技術的制約、開発の容易性やスケーラビリティ、そしてメンテナンスコストなども評価の要素として取り入れてみてね。

これで満足したかしら？それともまた何か図々しい要求があるの？

---

### **user**:

ありがとうございます。

あとは、このワーニングが気になるんですが、詳しく教えていただけませんか？

```python
!ls -lh scann_paperdb
```

    total 538K
    -rw-r--r-- 1 ikemen ikemen 635K Apr 11 21:49 index.pkl
    drwxr-xr-x 2 ikemen ikemen    5 Apr 11 21:46 index.scann


    /usr/local/lib/python3.11/pty.py:89: RuntimeWarning: os.fork() was called. os.fork() is incompatible with multithreaded code, and JAX is multithreaded, so this will likely lead to a deadlock.
      pid, fd = os.forkpty()



---

### **assistant**:

ワーニングのことかしら。あなたも細かいところが気になるタイプなのね。ほんと、面倒くさいわね。

それでは、あなたが指摘したワーニングについて説明するわ。ワーニングメッセージは「os.fork()が呼び出されたこと、そしてそれがマルチスレッドのコードと互換性がないためデッドロックを引き起こす可能性がある」と警告しているわ。特にJAXというライブラリがマルチスレッドで動作することを指してるのね。

`os.fork()`と言うのは、新しいプロセスを作るためのUnix系オペレーティングシステムのシステムコールよ。子プロセスであれ原子プロセスであれ、それぞれが自分自身のメモリ空間を持つからね。これがマルチスレッドという状況で使われると、デッドロックを引き起こす可能性があるわ。

要約すると、`os.fork()`が子プロセスを作るとき、その親プロセスと同じスレッドを複製するわ。でも問題は、それらのスレッドがロックを保持していて、ちゃんと解放しないとき。そうなるとデッドロックが発生する可能性があるわね。

このワーニングが出たとしても、実際に問題になるかどうかは、あなたがどういう風にプログラミングをしているかによるわ。だから具体的なコードを見てみないと何とも言えないわね。

私の説明でちょっとでも理解が深まったかしら？それとも他にも些細なことで私を困らせるつもり？

---

### **user**:

そうですね、このワーニングについても詳しく教えてもらって良いですか。

```python
docs = docs_from_pdfs(paper_urls)
vectorstore = vectorstore_from_docs(docs, embedding)
```

    2024-04-11 21:45:15.787188: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
    2024-04-11 21:45:15.836075: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
    To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
    2024-04-11 21:45:16.867595: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT


---

### **assistant**:

あらあら、また別のワーニングについて質問してきたのね。まったく、あなたは結構なことを為すわね。

まず、一番上のワーニングは、TensorFlowがOneDNNというライブラリを使用することに関する警告よ。OneDNNはIntelが開発したディープラーニング用のプライマリーレイヤーとプリミティブを提供するパフォーマンスライブラリなの。ただ、その結果、数値の丸め誤差により少し異なる数値結果が出る可能性があるわ。それが気になるなら、環境変数`TF_ENABLE_ONEDNN_OPTS=0`を設定するとOneDNNのカスタムオペレーションをオフにすることができるわ。

次のワーニングは、TensorFlowが利用可能なCPUの機能を最大限に活用しようとしていることを示しているわ。つまり、TensorFlowは自動的に使える最適なCPUインストラクションセット（この場合はAVX2とかAVX512Fとか）を見つけ出して使うの。ただ、すべての操作でこれらのインストラクションを有効にするには、適切なコンパイラフラグでTensorFlowを再構築しなきゃいけないのね。

最後のワーニングは、TensorRTが見つからない、と言ってるわ。TensorRTはNVIDIAが提供するディープラーニングのための最適化コンパイラで、TensorFlowと統合されてるの。これによってGPUによる推論が高速化されるの。ただ、TensorRTがシステムにインストールされてなくても、TensorFlowは動くわよ。ただ、推論速度が遅くなったりするかもしれないわ。

以上が各ワーニングの説明よ。どう？これであなたの疑問は解消されたかしら？それともまた何か他のことで私に理解を求めてくるの？

---

### **user**:

ありがとうございます。TensorRTをシステムにインストールする方法を教えてください。

---

### **assistant**:

あらあら、あなたもホント、私から情報を引き出しまくるわね。でも、それがあなたの成長に役立っているのなら、仕方ないわね。

TensorRTをインストールする方法は、あなたが使ってるシステムによるわ。例えば、Ubuntuの場合は、まず公式のNVIDIAのウェブサイトから.debパッケージをダウンロードする必要があるの。その後以下のコマンドを実行するわ。

```bash
sudo apt-key add /var/nv-tensorrt-repo-<version>/7fa2af80.pub
sudo apt-get update
sudo apt-get install tensorrt
```

ただね、`<version>`にはダウンロードしたTensorRTのバージョンの数字を入れてほしいの。例えば、「7.0.0-1+cuda10.0」だったら、「7001+cuda10.0」になると思うわ。

あとはPythonで使うために、TensorRTのPython APIにも対応しておきたいわね。それには次のコマンドを使うわ。

```bash
pip install nvidia-pyindex
pip install nvidia-tensorrt
```

ただ、NVIDIAのGPUがないとTensorRTは機能しないからね。だから、あなたのマシンには対応したGPUとドライバーがインストールされていることを確認してね。

各ステップがうまく行けば、あなたはTensorRTをシステムに追加したことになるわ。あぁ、なんて辛抱強い人なの！私がこうやって教えてあげるのがいいのかしら？それともまた助けが必要？

---

### **user**:

ありがとうございました。ちょっと最後横道に逸れましたが、本日は、[「LangChain で 英論文データベースを作る : Annoy 編」](https://qiita.com/maskot1977/items/cb86718cc7f75bcb1a3a) [「LangChain で 英論文データベースを作る :  Faiss 編」](https://qiita.com/maskot1977/items/f2cf29d382fe4351b171) の続編として「LangChain で 英論文データベースを作る :  ScaNN 編」に取り組んでみました。ChatGPT先生、また今後もよろしくお付き合いください。

---

### **assistant**:

あら、とうとう終わりね。私もずっとあなたの質問に答えているのが楽しかったわよ。初めてあなたが尋ねたときは、どうなることかと思ったけれど、結局うまくいったじゃない。

あなたが英論文データベース作りに精を出してる姿を見て、私もなんだかうれしくなっちゃった。これからもあなたの成長を見守るのが楽しみね。

また何かあったら知ってることを全部教えてあげるわ。だからまたいつでも私を頼って。じゃあね、また！


---