増え続ける研究出版物は、学問的知識を構成するための効率的な方法を必要とします。このタスクは通常、監視された根本的なクラスのスキームを開発し、最も関連性の高いクラスに出版物を割り当てることを伴います。この記事では、埋め込み量子化と大規模な言語モデル(LLM)パイプラインを使用して、エンドツーエンドの自動ソリューションを実装します。私たちのケーススタディは、2024年7月までに公開されたComputational Linguistics(CS.CL)からの25,000のARXIV出版物のデータセットから始まります。
私たちのアプローチは、3つの重要なタスクに焦点を当てています。(i)ARXIVデータセットの関連するコレクションへの監視されていないクラスタリング、(ii)各クラスター内の潜在的なテーマ構造を発見し、(iii)テーマ構造に基づいて候補分類スキームを作成します。
そのコアでは、クラスタリングタスクでは、非標識データセット内で十分な数の同様の例を識別する必要があります。これは、コーパス内のセマンティック関係をキャプチャし、例の類似性リンクを確立するためのクラスタリングアルゴリズムへの入力機能として提供できるため、埋め込みの自然なタスクです。最初に、データセットの(タイトル:要約)ペアを、Bert-Alibiベースの注意モデルであるJina-embeddings-V2を使用して、埋め込み表現に変換することから始めます。文とカスタム実装の両方を使用して、スカラー量子化を適用します。
クラスタリングの場合、hdbscanを縮小した次元空間で実行し、 eomとleafクラスタリング方法を使用して結果を比較します。さらに、(u) float32表現の代わりに(u)int8埋め込み量子化を使用すると、このプロセスに影響するかどうかを調べます。
ARXIV出版物の各クラスター内の潜在的なトピックを明らかにするために、LangchainとPydanticとMistral-7B-Instruct-V0.3(およびGPT-4O、比較のために含まれる)をLLM-Pipelineに組み合わせます。その後、出力は、階層分類法を生成するためにClaude Sonnet 3.5をガイドする洗練されたプロンプトテンプレートに組み込まれます。
結果は、各トピックが少なくとも100出版物で構成されている35の新興研究トピックを示唆しています。これらは、計算言語学の分野(CS.CL)の7つの親クラス内で編成されています。このアプローチは、高レベルのARXIVカテゴリで階層候補スキームを自動的に生成し、分類法を効率的に完成させるためのベースラインとして機能し、学術文献の増加によってもたらされる課題に対処することができます。
埋め込み量子化とLLMパイプラインを埋め込んだ学術文献の分類学の完了
埋め込みは、表現するデータのセマンティック情報をカプセル化するテキスト、画像、オーディオなどの実際のオブジェクトの数値表現です。 AIモデルは、クラスタリング、情報検索、セマンティック理解タスクなどの下流のアプリケーションで複雑な知識ドメインを理解するために使用されます。
最大8192トークンを収容できるオープンソーステキスト埋め込みモデルであるJina-embeddings-V2 [1]を使用して、ARXIV出版物から768次元スペースにペアをマッピングします。これにより、タイトル、要約、および関連する可能性のあるその他のドキュメントセクションに十分に大きなシーケンス長が提供されます。他のモデルに存在する従来の512トークンの制限を克服するために、Jina-embeddings-V2は双方向Alibi [2]をBERTフレームワークに組み込みます。 ALIBI(線形バイアスを伴う注意)は、位置埋め込みを導入する代わりに、自己触媒層内で位置情報を直接エンコードすることにより、入力長(つまり、2048トークンを超えるシーケンス)を可能にします。実際には、距離に比例するペナルティでクエリキーの注意スコアをバイアスし、近接トークン間の相互の注意を強く支持します。
Jina-embeddings-V2モデルを使用する最初のステップは、抱きしめるフェイスハブで利用可能な最先端のモデルにアクセスするためのフレームワークである文であるTransformersを介してロードすることです。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer ( 'jinaai/jina-embeddings-v2-base-en' , trust_remote_code = True ) batch_size = 64を使用して、データセットのペアをエンコードします(タイトル:要約)。これにより、GPUなどのハードウェアアクセラレータでの並列計算が可能になります(より多くのメモリが必要な場合は犠牲を払っていますが):
from datasets import load_dataset
ds = load_dataset ( "dcarpintero/arxiv.cs.CL.25k" , split = "train" )
corpus = [ title + ':' + abstract for title , abstract in zip ( ds [ 'title' ], ds [ 'abstract' ])]
f32_embeddings = model . encode ( corpus ,
batch_size = 64 ,
show_progress_bar = True )Corpora間のセマンティックな類似性は、埋め込みの内部産物として簡単に計算できるようになりました。次のヒートマップでは、各エントリ[x、y]は、模範的な「タイトル」文の埋め込み製品に基づいて色付けされています[x]および[y]。
埋め込みを使用したCs.Cl Arxiv-Titlesのセマンティックシミラリー
埋め込みのスケールは困難な場合があります。現在、最先端のモデルは、各埋め込みをfloat32として表しています。これには、4バイトのメモリが必要です。 Jina-embeddings-v2はテキストを768次元空間にマッピングすることを考えると、データセットのメモリ要件は、出版記録に関連するインデックスやその他のメタデータなしで、約73 MBになります。
25 , 000 embeddings * 768 dimensions / embedding * 4 bytes / dimension = 76 , 800 , 000 bytes
76 , 800 , 000 bytes / ( 1024 ^ 2 ) ≈ 73.24 MBただし、より大きなデータセットを使用すると、メモリ要件と関連するコストが大幅に増加する可能性があります。
| 埋め込み 寸法 | 埋め込み モデル | 2.5m arxiv要約 | 60.9m ウィキペディアページ | 100m 埋め込み |
|---|---|---|---|---|
| 384 | All-Minilm-L12-V2 | 3.57 GB | 85.26 GB | 142.88 GB |
| 768 | All-MPNet-Base-V2 | 7.15 GB | 170.52 GB | 285.76 GB |
| 768 | Jina-embeddings-v2 | 7.15 GB | 170.52 GB | 285.76 GB |
| 1536 | Openai-Text-embeding-3-Small | 14.31 GB | 341.04 GB | 571.53 GB |
| 3072 | Openai-Text-embedding-3-large | 28.61 GB | 682.08 GB | 1.143 TB |
メモリ保存を達成するために使用される手法は量子化です。このアプローチの背後にある直感は、範囲[ f_max 、 f_min ]をより小さな範囲の固定点[ q_max 、 q_min ]にマッピングすることにより、浮動小数点値を離散化できることです。実際には、これは通常、32ビットの浮動小数点の精度を、8ビット(スカラー量子化)または1ビット値(バイナリ量子化)などのビット幅を低く減らします。
スカラー埋め込み量子化 - float32から(u)int8まで
ジナ生成された埋め込みの頻度分布をプロットすることにより、値は実際に比較的狭い範囲に集中していることがわかります[-2.0、+2.0]。これは、情報を大幅に損なうことなく、 float32値を256 (u)int8バケットに効果的にマッピングできることを意味します。
import matplotlib . pyplot as plt
plt . hist ( f32_embeddings . flatten (), bins = 250 , edgecolor = 'C0' )
plt . xlabel ( 'float-32 jina-embeddings-v2' )
plt . title ( 'distribution' )
plt . show ()オリジナルFloat32 Jina-embeddings-V2分布
分布の正確な[min, max]値を計算できます。
> >> np . min ( f32_embeddings ), np . max ( f32_embeddings )
( - 2.0162134 , 2.074683 )スカラー量子化を実装する最初のステップは、埋め込みのキャリブレーションセットを定義することです。典型的な出発点は、10K埋め込みのサブセットであり、この場合、元のfloat32埋め込み値のほぼ99.98%をカバーします。キャリブレーションの使用は、各ディメンションに沿って代表的なf_min値とf_max値を取得して、計算オーバーヘッドと、より大きなデータセットに表示される可能性のある外れ値によって引き起こされる潜在的な問題を減らすことを目的としています。
def calibration_accuracy ( embeddings : np . ndarray , k : int = 10000 ) -> float :
calibration_embeddings = embeddings [: k ]
f_min = np . min ( calibration_embeddings , axis = 0 )
f_max = np . max ( calibration_embeddings , axis = 0 )
# Calculate percentage in range for each dimension
size = embeddings . shape [ 0 ]
avg = []
for i in range ( embeddings . shape [ 1 ]):
in_range = np . sum (( embeddings [:, i ] >= f_min [ i ]) & ( embeddings [:, i ] <= f_max [ i ]))
dim_percentage = ( in_range / size ) * 100
avg . append ( dim_percentage )
return np . mean ( avg )
acc = calibration_accuracy ( f32_embeddings , k = 10000 )
print ( f"Average percentage of embeddings within [f_min, f_max] calibration: { acc :.5f } %" )
> >> Average percentage of embeddings within [ f_min , f_max ] calibration : 99.98636 %スカラー量子化の2番目と3番目のステップ(コンピューティングスケールとゼロポイント、およびエンコード)は、文変換器で簡単に適用でき、元のfloat32表現と比較して4倍のメモリを節約できます。さらに、マトリックスの乗算は整数算術により迅速に実行できるため、より高速な算術操作の恩恵を受けます。
from sentence_transformers . quantization import quantize_embeddings
# quantization is applied in a post-processing step
int8_embeddings = quantize_embeddings (
np . array ( f32_embeddings ),
precision = "int8" ,
calibration_embeddings = np . array ( f32_embeddings [: 10000 ]),
) f32_embeddings . dtype , f32_embeddings . shape , f32_embeddings . nbytes
>> > ( dtype ( 'float32' ), ( 25107 , 768 ), 77128704 ) # 73.5 MB
int8_embeddings . dtype , int8_embeddings . shape , int8_embeddings . nbytes
>> > ( dtype ( 'int8' ), ( 25107 , 768 ), 19282176 ) # 18.3 MB
# calculate compression
( f32_embeddings . nbytes - int8_embeddings . nbytes ) / f32_embeddings . nbytes * 100
>> > 75.0完全性のために、これらの3つのステップを説明するために、スカラー量子化方法を実装してください。
def scalar_quantize_embeddings ( embeddings : np . ndarray ,
calibration_embeddings : np . ndarray ) -> np . ndarray :
# Step 1: Calculate [f_min, f_max] per dimension from the calibration set
f_min = np . min ( calibration_embeddings , axis = 0 )
f_max = np . max ( calibration_embeddings , axis = 0 )
# Step 2: Map [f_min, f_max] to [q_min, q_max] => (scaling factors, zero point)
q_min = 0
q_max = 255
scales = ( f_max - f_min ) / ( q_max - q_min )
zero_point = 0 # uint8 quantization maps inherently min_values to zero
# Step 3: encode (scale, round)
quantized_embeddings = (( embeddings - f_min ) / scales ). astype ( np . uint8 )
return quantized_embeddings calibration_embeddings = f32_embeddings [: 10000 ]
beta_uint8_embeddings = scalar_quantize_embeddings ( f32_embeddings , calibration_embeddings ) beta_uint8_embeddings [ 5000 ][ 64 : 128 ]. reshape ( 8 , 8 )
array ([[ 187 , 111 , 96 , 128 , 116 , 129 , 130 , 122 ],
[ 132 , 153 , 72 , 136 , 94 , 120 , 112 , 93 ],
[ 143 , 121 , 137 , 143 , 195 , 159 , 90 , 93 ],
[ 178 , 189 , 143 , 99 , 99 , 151 , 93 , 102 ],
[ 179 , 104 , 146 , 150 , 176 , 94 , 148 , 118 ],
[ 161 , 138 , 90 , 122 , 93 , 146 , 140 , 129 ],
[ 121 , 115 , 153 , 118 , 107 , 45 , 70 , 171 ],
[ 207 , 53 , 67 , 115 , 223 , 105 , 124 , 158 ]], dtype = uint8 )文の変圧器を使用して量子化された埋め込みのバージョンを継続します(カスタム実装も結果分析に含まれています)。
# `f32_embeddings` => if you prefer to not use quantization
# `beta_uint8_embeddings` => to check our custom implemention
embeddings = int8_embeddings このセクションでは、元の高次元空間(768)からペアを埋め込む(タイトル:要約)の2段階投影を実行します。
5 dimensions(x, y)座標で視覚表現を有効にするための2 dimensions 。両方の投影では、ローカルデータ構造とグローバルデータ構造の両方を維持する上で知られている人気のある次元削減手法であるUMAP [3]を採用しています。実際には、これにより、高次元の埋め込みで複雑なデータセットを処理するための好ましい選択肢になります。
import umap
embedding_5d = umap . UMAP ( n_neighbors = 100 , # consider 100 nearest neighbors for each point
n_components = 5 , # reduce embedding space from 768 to 5 dimensions
min_dist = 0.1 , # maintain local and global balance
metric = 'cosine' ). fit_transform ( embeddings )
embedding_2d = umap . UMAP ( n_neighbors = 100 ,
n_components = 2 ,
min_dist = 0.1 ,
metric = 'cosine' ). fit_transform ( embeddings )次のステップでHDBSCANクラスタリングを適用すると、見つかったクラスターは、UMAPがローカル構造をどのように保存するかに影響されることに注意してください。 n_neighbors値が小さいことは、UMAPがローカル構造により焦点を合わせますが、より大きな値はより多くのグローバルな表現をキャプチャできるようにすることを意味します。これは、データの全体的なパターンを理解するのに有益です。
縮小(タイトル:要約)埋め込みは、クラスタリングアルゴリズムの入力機能として使用できるようになり、埋め込み距離に基づいて関連カテゴリの識別を可能にします。
HDBSCAN(ノイズ付きアプリケーションの階層密度ベースの空間クラスタリング)[4]を選択しました。クラスターの数を事前に指定する必要があるK-meansとは異なり、HDBSCANには、クラスターに含める最小数の例を確立する重要なハイパーパラメーターnが1つしかありません。
HDBSCANは、データポイントの密度に応じてデータ空間を最初に変換することで機能し、クラスター形成により魅力的な密度の高い領域(データポイントが密接に近い領域)になります。このアルゴリズムは、ハイパーパラメーターnによって確立された最小クラスターサイズに基づいて、クラスターの階層を構築します。これにより、ノイズ(スパースエリア)と密な領域(潜在的なクラスター)を区別できます。最後に、HDBSCANはこの階層を凝縮して、最も持続的なクラスターを導き出し、異なる密度と形状のクラスターを識別します。密度ベースの方法として、外れ値を検出することもできます。
import hdbscan
hdbs = hdbscan . HDBSCAN ( min_cluster_size = 100 , # conservative clusters' size
metric = 'euclidean' , # points distance metric
cluster_selection_method = 'leaf' ) # favour fine grained clustering
clusters = hdbs . fit_predict ( embedding_5d ) # apply HDBSCAN on reduced UMAP cluster_selection_methodは、hdbscanがツリー階層からフラットクラスターを選択する方法を決定します。この場合、 eom (質量の過剰)クラスター選択方法を使用して、量子化の埋め込みと組み合わせて、いくつかのより大きく、それほど特定のクラスターを作成する傾向がありました。これらのクラスターは、意味のある潜在的なトピックを抽出するために、さらに再閉鎖プロセスを必要としていました。代わりに、 leaf選択方法に切り替えることにより、アルゴリズムを導き、クラスター階層から葉のノードを選択しました。
HDBSCAN EOM & Leaf Clustering Method比較は、Int8-dembedding-quantizationを使用しています
クラスタリングステップを実行した後、Mistral-7B-Instruct [5]などのLLMをPydanticおよびLangchainなどのLLMを組み合わせて、構成可能な構造化形式で出力を生成するLLMパイプラインを作成することにより、各クラスターの潜在的なトピックを推測する方法を説明します。
Pydantic Modelsは、 pydantic.BaseModelに由来するクラスであり、フィールドをタイプ解決の属性として定義します。それらはPython Dataclassesに似ています。しかし、それらは、検証、シリアル化、 JSONスキーマ生成など、さまざまな操作を最適化する微妙であるが大きな違いで設計されています。 Topicクラスは、 labelという名前のフィールドを定義しています。これにより、フリーフォームテキストブロックではなく、構造化された形式でLLM出力が生成され、処理と分析が容易になります。
from pydantic import BaseModel , Field
class Topic ( BaseModel ):
"""
Pydantic Model to generate an structured Topic Model
"""
label : str = Field (..., description = "Identified topic" )Langchainプロンプトテンプレートは、ユーザーの入力とパラメーターを言語モデルの指示に変換するための事前に定義されたレシピです。ここでは、意図したタスクのプロンプトを定義します。
from langchain_core . prompts import PromptTemplate
topic_prompt = """
You are a helpful research assistant. Your task is to analyze a set of research paper
titles related to Natural Language Processing, and determine the overarching topic.
INSTRUCTIONS:
1. Based on the titles provided, identify the most relevant topic:
- Ensure the topic is concise and clear.
2. Format Respose:
- Ensure the title response is in JSON as in the 'OUTPUT OUTPUT' section below.
- No follow up questions are needed.
OUTPUT FORMAT:
{{"label": "Topic Name"}}
TITLES:
{titles}
"""次に、Langchain Expression Language(LCEL)を使用してトピックモデリングパイプラインを作成して、プロンプトテンプレートをLLM入力にし、推論出力をJSONとして解析します。
from langchain . chains import LLMChain
from langchain_huggingface import HuggingFaceEndpoint
from langchain_core . output_parsers import PydanticOutputParser
from typing import List
def TopicModeling ( titles : List [ str ]) -> str :
"""
Infer the common topic of the given titles w/ LangChain, Pydantic, OpenAI
"""
repo_id = "mistralai/Mistral-7B-Instruct-v0.3"
llm = HuggingFaceEndpoint (
repo_id = repo_id ,
temperature = 0.2 ,
huggingfacehub_api_token = os . environ [ "HUGGINGFACEHUB_API_TOKEN" ]
)
prompt = PromptTemplate . from_template ( topic_prompt )
parser = PydanticOutputParser ( pydantic_object = Topic )
topic_chain = prompt | llm | parser
return topic_chain . invoke ({ "titles" : titles })モデルが各クラスターのトピックを推測できるようにするために、LLM入力の一部として各クラスターの25の紙のタイトルのサブセットを含めます。
topics = []
for i , cluster in df . groupby ( 'cluster' ):
titles = cluster [ 'title' ]. sample ( 25 ). tolist ()
topic = TopicModeling ( titles )
topics . append ( topic . label )各ARXIV出版物を対応するクラスターに割り当てましょう。
n_clusters = len ( df [ 'cluster' ]. unique ())
topic_map = dict ( zip ( range ( n_clusters ), topics ))
df [ 'topic' ] = df [ 'cluster' ]. map ( topic_map )階層分類法を作成するために、各クラスターに対応する特定された研究トピックを階層式スキームに整理するために、Claude Sonnet 3.5を導くプロンプトを作成します。
from langchain_core . prompts import PromptTemplate
taxonomy_prompt = """
Create a comprehensive and well-structured taxonomy
for the ArXiv cs.CL (Computational Linguistics) category.
This taxonomy should organize subtopics in a logical manner.
INSTRUCTIONS:
1. Review and Refine Subtopics:
- Examine the provided list of subtopics in computational linguistics.
- Ensure each subtopic is clearly defined and distinct from others.
2. Create Definitions:
- For each subtopic, provide a concise definition (1-2 sentences).
3. Develop a Hierarchical Structure:
- Group related subtopics into broader categories.
- Create a multi-level hierarchy, with top-level categories and nested subcategories.
- Ensure that the structure is logical and intuitive for researchers in the field.
4. Validate and Refine:
- Review the entire taxonomy for consistency, completeness, and clarity.
OUTPUT FORMAT:
- Present the final taxonomy in a clear, hierarchical format, with:
. Main categories
.. Subcategories
... Individual topics with their definitions
SUBTOPICS:
{taxonomy_subtopics}
""" インタラクティブな散布図を作成しましょう。
chart = alt . Chart ( df ). mark_circle ( size = 5 ). encode (
x = 'x' ,
y = 'y' ,
color = 'topic:N' ,
tooltip = [ 'title' , 'topic' ]
). interactive (). properties (
title = 'Clustering and Topic Modeling | 25k arXiv cs.CL publications)' ,
width = 600 ,
height = 400 ,
)
chart . display () float32埋め込み表現とint8文のトランスの量子化を使用して、クラスタリング結果を比較してください。
float32およびQuantized-int8埋め込みを使用したHDBSCANリーフクラスタリング(文と変換者 - 定量化)
現在、カスタム量子化実装と同じ比較を実行します。
float32およびQuantized-uint8エンミングを使用したHDBSCANリーフクラスタリング(カスタム定量化 - 実装)
float32および(u)int8の量子化された埋め込みを使用したクラスタリング結果は、明確に定義されたクラスターの同様の一般的なレイアウトを示しています。
特に、埋め込み量子化を使用すると、両方のケースがわずかに粒状クラスタリング(35クラスター対31)で、意味的に一貫性があると思われることが観察できます。この違いの暫定的な仮説は、スカラー量子化がHDBSCANクラスタリングアルゴリズムを逆説的に導き、以前にグループ化されたポイントを分離する可能性があるということです。
これは、(i)ノイズ(量子化はデータに小さなノイズの多いバリエーションを作成する可能性があり、一種の正規化効果があり、より機密のクラスタリングの決定につながる可能性があります)、または(ii)数値精度と距離計算の変化の違いが原因である可能性があります(これにより、 float32表現ではないポイント間の特定の違いを増幅できます)。クラスタリングに対する量子化の意味を完全に理解するには、さらなる調査が必要です。
スキーム全体は、cs.cl.taxonomyで入手できます。このアプローチは、高レベルのARXIVカテゴリのクラスの候補スキームを自動的に識別するベースラインとして機能する可能性があります。
. Foundations of Language Models
.. Model Architectures and Mechanisms
... Transformer Models and Attention Mechanisms
... Large Language Models (LLMs)
.. Model Optimization and Efficiency
... Compression and Quantization
... Parameter-Efficient Fine-Tuning
... Knowledge Distillation
.. Learning Paradigms
... In-Context Learning
... Instruction Tuning
. AI Ethics, Safety, and Societal Impact
.. Ethical Considerations
... Bias and Fairness in Models
... Alignment and Preference Optimization
.. Safety and Security
... Hallucination in LLMs
... Adversarial Attacks and Robustness
... Detection of AI-Generated Text
.. Social Impact
... Hate Speech and Offensive Language Detection
... Fake News Detection
[...]
@article{carpintero2024
author = { Diego Carpintero},
title = {Taxonomy Completion with Embedding Quantization and an LLM-Pipeline: A Case Study in Computational Linguistics},
journal = {Hugging Face Blog},
year = {2024},
note = {https://huggingface.co/blog/dcarpintero/taxonomy-completion},
}