chore: LLM基礎知識
kyonenya opened this issue · comments
OpenAI API
presence_penalty
-2.0から2.0の値を取り、既に出てきた単語をもう一度使うかどうかを指定します。
-2.0に近いと同じ単語を繰り返し使うようになり、2.0に近いと同じ単語は繰り返し使いづらくなります
デフォルトはゼロです。frequency_penalty
こちらもpresence_penaltyと同じようなパラメータで-2.0から2.0の値を取り、出てきた回数が多いほどペナルティを大きくするものです。
presence_penaltyと同様に-2.0に近いと同じ単語を繰り返し使うようになり、2.0に近いと同じ単語は繰り返し使わなくなります。
presence_penaltyは1度でも使ったかどうか、ということにペナルティを加えますが、frequency_penaltyは使った回数に応じてペナルティを加えます。
こちらもデフォルトはゼロです。
パラメータ - OpenAI GPT-3 APIの使い方を解説 | 楽しみながら理解するAI・機械学習入門
- Models - OpenAI API
- "text-davinci-003" は Legacy で /v1/completion でしか動作しない
- "error": { "message": "This is not a chat model and thus not supported in the v1/chat/completions endpoint. Did you mean to use v1/completions?" }
- The maximum number of characters (not tokens) in each chunk.
テキスト補完とチャット補完の違い
Text Completionsと比較してChat Completionsの特徴を見ていきましょう。
専用のモデル
Text Completionsでは、代表的なGPT-3.5モデルとしてtext-davinci-003が提供されていましたが、Chat Completionsでは、チャット補完に最適化された新しいモデルgpt-3.5-turboが追加されました。text-davinci-003は、高度な自然言語処理タスクでの利用が想定されている一方、 gpt-3.5-turboは小規模で速度が速く、比較的簡単な自然言語処理タスクでの利用が想定されています。なお、これらに互換性はなく、Chat Completionsでtext-davinci-003を使用することはできず、同様に、Text Completionsでgpt-3.5-turboを使用することはできません。
一連の会話に基づいた補完
Text Completionsでは単一のプロンプトを入力しますが、Chat Completionsでは一連の会話(誰がどんな発言をしたのか)をメッセージのリストとして入力できます。これにより、以前の会話のコンテキストに基づいた補完が実現可能です。たとえば、「猫の名前は?」という質問について、Text Completionsの場合、どの猫を指しているかは分かりません。しかし、Chat Completionsの場合、過去の会話から「吾輩は猫である」というコンテキストに基づいて回答します。
ChatGPT入門: Chat Completions APIでオリジナルのチャットボットを作ろう! - Qiita
- Prompt Templates | 🦜️🔗 Langchain.js
- LangChain Promptとは?【Templates・Example Selectors・Output Parsers】
- Jestの一括テストみたいなやつもあるな
- PromptTemplate(これ使う)、FewShotPromptTemplate、ChatPromptTemplateがある
OpenAIのEmbeddingとは?
自然言語処理において、単語や文章を「数値化する技術」
・単語や文章をベクトル表現できる(ベクトル空間にマッピングする)
→類似するものは近くに配置され、異なるものは離れた位置に配置される
・「text-embedding-ada-002」モデルの入力トークンの上限は「8191」
・「text-embedding-ada-002」モデルのベクトルは1536次元である
OpenAIのEmbeddingの使い方_0747 – Rainbow Engine
- 関連記事の処理を OpenAI の Embedding に切り替えてみた | エビスコム - EBISUCOM
- 形態素解析いらなくなるやん
- 安すぎ、ElasticSearch死んだな:「また、API の利用料は 1000トークンあたり $0.0004(約 0.06 円)です(gpt-3.5-turbo と比較すると 1/5 です)」
- OpenAIのEmbeddingについて検証してみた - Qiita
Vercel AI SDK
- Completion API - OpenAI - Vercel AI SDK
- Getting Started - Vercel AI SDK
- prompt の例。use client するらしい
- ai/examples/next-openai/app/api/chat/route.ts at main · vercel-labs/ai · GitHub
- few shots に ? を含めてる。出鱈目を作るな、分からないなら分からないと言え、か
- ai/examples/next-openai/app/api/chat/route.ts at main · vercel-labs/ai · GitHub
- Edge Functions - Vercel についてざっくり理解
- 「Edge Functions の最大実行時間は 30s であるが、レスポンスを返すまでは 1.5s 以内にする 必要がある。レスポンスを返した後、バックグラウンドで非同期のワークロードを続行することは可能」
- セグメントランタイムオプション - Next.js
- 「Next.jsアプリケーションでは、個々のルートセグメントのランタイムを指定できます。これを行うには、runtimeと呼ばれる変数を宣言し、それをエクスポートします。変数は文字列でなければならず'nodejs'または'edge'ランタイムのいずれかの値を持つ必要があります」
- Vercel AI SDKでAIチャットアプリが10分で完成!実験・開発レポート|komz
- Vercel AI SDKがすごい!!!
- Vercel AI もedge上で実行なんだな、なんでやろ
- Cloudflare Workers上でLangChainを動かしストリームで回答を返すようにしてみる | DevelopersIO
実装例
- next-langchain-sample/app/page.tsx at main · arafipro/next-langchain-sample · GitHub
- Next.jsでの実装例
- 環境変数のAPI KeyをNEXT_PUBLIC_にしてるのは普通にインシデント級のミスなのでNG
loadQA...
系の用意されてる一気通貫メソッドはPrompt Templateで独自実装してみるか- loadQAMapReduceChain - OpenAI APIとLangChainを使ってPDFの内容を質問したい
- langchainjs/langchain/src/chains/question_answering/load.ts at 37dfc77c2926157c89b657e31c2c16f8b7647200 · hwchase17/langchainjs
- langchainjs/langchain/src/chains/question_answering/map_reduce_prompts.ts at 37dfc77c2926157c89b657e31c2c16f8b7647200 · hwchase17/langchainjs · GitHub
combine_prompt
でfew shotしてる
- ChatGPTの文字数制限と解決方法を解説する記事を公開 | NEWSCAST
- トークン数の計算について。英語なら一単語まで1トークンなのに日本語は漢字一文字だけで2-3トークン使っちゃうのね……
- Python版のコード完全版
- ChatGPTで独自データを学習させて回答してもらう方法 - Qiita
- 主要引数の chunk_size, chunk_overlap はどのように設定するべきか
Langchain.js
- LangChainのTextSplitterを試す|npaka
- CharacterTextSplitter と、 RecursiveCharacterTextSplitter の違い
- fake
- OpenAI APIとLangChainを使ってPDFの内容を質問したい
- データを分割するサイズを設定するために
CharacterTextSplitter
を使います - fake
- データを分割するサイズを設定するために
- LangChain.js クイックスタートガイド - TypeScript版|npaka
- あんまり関係ない
プロンプト
PDFテキスト分割
分割の設定をする - OpenAI APIとLangChainを使ってPDFの内容を質問したい
// これ参考にしちゃダメだな
データを分割するサイズを設定するために
CharacterTextSplitter
を使います。
以下のコードのようにインポートします。
import { CharacterTextSplitter } from "langchain/text_splitter";
次に新しいオブジェクトを作成し、変数 splitter
に渡します。
そのコンストラクタに3つの引数としてを渡します。
separator
: テキストをチャンクに分割するために使用される文字。
chunkSize
: 分割後の各チャンク(断片)の最大文字数です。
chunkOverlap
: 各チャンクが前のチャンクと重複する文字数。
const splitter = new CharacterTextSplitter({
separator: " ",
chunkSize: 512,
chunkOverlap: 24,
});
separator
をスペース
、chunkSize
を512
、chunkOverlap
を 24
で設定しました、
数値は以下の記事を参考にさせていだたきました。
ChatGPTで独自データを学習させて回答してもらう方法 - Qiita
データをチャンクに分割するコードはこのあたりです。
text_splitter = RecursiveCharacterTextSplitter(
# Set a really small chunk size, just to show.
chunk_size = 512,
chunk_overlap = 24,
length_function = count_tokens,
)
chunks2 = text_splitter.create_documents([text])
チャンクのサイズとチャンク同士のオーバラップする量を指定することができます。
このサイズは大きくしたりもしてみましたが、1000などにすると後のデータ検索時にChatGPTのトークンサイズ(4000)を超えてしまってエラーになったりすることが頻発したので、これくらいのサイズがちょうど良いのかもしれません。
TextSplitterの比較
RecursiveCharacterTextSplitter
お勧めの TextSplitter は RecursiveCharacterTextSplitter です。これは、"\n\n "から始まり、"\n"、""、というように、異なる文字で再帰的にドキュメントを分割します。これは、意味的に関連するすべてのコンテンツを、可能な限り同じ場所に維持しようとするので、良いことです。
ここで知っておくべき重要なパラメータは、chunkSizeとchunkOverlapです。 chunkSizeは、最終的なドキュメントの最大サイズ(文字数)を制御します。これは、テキストが変に分割されないようにするのに役立つことが多い。下の例では(説明のために)これらの値を小さく設定していますが、実際にはそれぞれデフォルトの1000と200になります。
RecursiveCharacterTextSplitter | 🦜️🔗 Langchain
CharacterTextSplitter
RecursiveCharacterTextSplitter の他に、より標準的な CharacterTextSplitter もあります。これは1種類の文字(デフォルトは"\n\n")だけを分割します。
CharacterTextSplitter | 🦜️🔗 Langchain
- faiss-node - Faiss | 🦜️🔗 Langchain
- Vector Storeには FAISS を利用
- Faiss Readerを使って、クエリに類似したノードのみのインデックスを作成する | DevelopersIO
Faiss (Vector Store)
python
text_splitter = RecursiveCharacterTextSplitter(
# Set a really small chunk size, just to show.
chunk_size = 512,
chunk_overlap = 24,
length_function = count_tokens,
)
chunks = text_splitter.create_documents([text])
# Get embedding model
embeddings = OpenAIEmbeddings()
# vector databaseの作成
db = FAISS.from_documents(chunks, embeddings)
# langchainをロードする。
# chain = load_qa_chain(OpenAI(temperature=0.2,max_tokens=1000), chain_type="stuff")
query = "ランプが点滅しているが、これは何が原因か?"
# VectoreStoreを検索
docs = db.similarity_search(query)
# VectoreStoreの検索結果とqueryを渡してChatGPTに回答させる
# chain.run(input_documents=docs, question=query)
ChatGPTで独自データを学習させて回答してもらう方法 - Qiita
Create a new index from a loader - Faiss | 🦜️🔗 Langchain
import { FaissStore } from "langchain/vectorstores/faiss";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { TextLoader } from "langchain/document_loaders/fs/text";
// Create docs with a loader
// const loader = new TextLoader("src/document_loaders/example_data/example.txt");
// const docs = await loader.load();
// Load the docs into the vector store
const vectorStore = await FaissStore.fromDocuments(
docs,
new OpenAIEmbeddings()
);
// Search for the most similar document
const resultOne = await vectorStore.similaritySearch("hello world", 1);
console.log(resultOne);
API Reference:
FaissStore from langchain/vectorstores/faiss
fromDocuments
Parameter | Type |
---|---|
docs | Document<Record<string, any>>[] |
embeddings | Embeddings |
dbConfig? | object |
dbConfig.docstore? | SynchronousInMemoryDocstore |
Returns
Promise<FaissStore>
similaritySearch() - FaissStore | 🦜️🔗 Langchain
Parameter | Type | Default value |
---|---|---|
query | string | undefined |
k | number | 4 |
filter | undefined | object | undefined |
Returns
Promise<Document<Record<string, any>>[]>
OpenAIEmbeddings | 🦜️🔗 Langchain
modelName
modelName: string = "text-embedding-ada-002"
Model name to use
Q: Where is the Valley of Kings?
const response = await openai.createCompletion({
model: "text-davinci-003",
prompt: "I am a highly intelligent question answering bot. If you ask me a question that is rooted in truth, I will give you the answer. If you ask me a question that is nonsense, trickery, or has no clear answer, I will respond with \"Unknown\".\n\nQ: What is human life expectancy in the United States?\nA: Human life expectancy in the United States is 78 years.\n\nQ: Who was president of the United States in 1955?\nA: Dwight D. Eisenhower was president of the United States in 1955.\n\nQ: Which party did he belong to?\nA: He belonged to the Republican Party.\n\nQ: What is the square root of banana?\nA: Unknown\n\nQ: How does a telescope work?\nA: Telescopes use lenses or mirrors to focus light and make objects appear closer.\n\nQ: Where were the 1992 Olympics held?\nA: The 1992 Olympics were held in Barcelona, Spain.\n\nQ: How many squigs are in a bonk?\nA: Unknown\n\nQ: Where is the Valley of Kings?\nA:",
temperature: 0,
max_tokens: 100,
top_p: 1,
frequency_penalty: 0.0,
presence_penalty: 0.0,
stop: ["\n"],
});
{
id: 'cmpl-7brqjPYzmdN45vd8DrVMS4xSiLjsv',
object: 'text_completion',
created: 1689259489,
model: 'text-davinci-003',
choices: [
{
text: ' The Valley of Kings is located in Luxor, Egypt.',
index: 0,
logprobs: null,
finish_reason: 'stop'
}
],
usage: { prompt_tokens: 233, completion_tokens: 12, total_tokens: 245 }
}
Done.
{
id: 'cmpl-7brvnL4wSWw62byhW7Wypp9LmB3Cg',
object: 'text_completion',
created: 1689259803,
model: 'text-davinci-003',
choices: [
{
text: ' The name of the company is Procter & Gamble.',
index: 0,
logprobs: null,
finish_reason: 'stop'
}
],
usage: { prompt_tokens: 2212, completion_tokens: 12, total_tokens: 2224 }
}
ChatPDF
シンプルにすごい……
Welcome to the exciting news release from The Procter & Gamble Company! The company has announced a remarkable increase in net sales and organic sales, along with a rise in sales growth and cash return guidance. Additionally, P&G has maintained its fiscal year EPS growth guidance range.
Example questions:
- What factors contributed to the increase in P&G's net sales and organic sales?
- How has P&G returned cash to its shareholders, and what is the significance of the recent dividend increase?
- What is P&G's adjusted free cash flow productivity, and how is it calculated?
What factors contributed to the increase in P&G's net sales and organic sales?
According to (Page 15), P&G's net sales growth for January-March 2023 was 4%, with organic sales growth of 7%. The growth was driven by a combination of factors, including higher pricing, innovation-based volume growth, and the impact of acquisitions and divestitures. Additionally, (Page 15) shows that P&G's total net sales growth for FY 2023 is estimated to be around 6%, with organic sales growth of approximately 1%.
# https://qiita.com/windows222/items/232f05bafa95a9c8874e#%E3%82%B3%E3%83%BC%E3%83%89
# https://colab.research.google.com/drive/1n0qtXXUdHdK376VjFM-rtAR9PWIPjNXi?usp=sharing
# # 上級者向けの方法 チャンクに分割。これだとメタデータの情報が取れない
# Step 1: Convert PDF to text
doc = textract.process("sample_document2.pdf")
# Step 2: Save to .txt and reopen (helps prevent issues)
# ChatGPT: このステップはPythonではエンコーディングの問題を回避するために行っていますが、JavaScriptでは通常このステップは不要です。
with open('attention_is_all_you_need.txt', 'w') as f:
f.write(doc.decode('utf-8'))
with open('attention_is_all_you_need.txt', 'r') as f:
text = f.read()
# Step 3: Create function to count tokens
tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")
def count_tokens(text: str) -> int:
return len(tokenizer.encode(text))
# Step 4: Split text into chunks
text_splitter = RecursiveCharacterTextSplitter(
# Set a really small chunk size, just to show.
chunk_size = 512,
chunk_overlap = 24,
length_function = count_tokens,
)
chunks2 = text_splitter.create_documents([text])