Apache Cassandra
このセクションでは、ドキュメントの埋め込みを保存し、類似性検索を実行するための CassandraVectorStore
のセットアップについて説明します。
Apache Cassandra とは何ですか?
Apache Cassandra ® (英語) は、線形スケーラビリティ、実証済みのフォールトトレランス、低レイテンシで知られる真のオープンソース分散データベースであり、ミッションクリティカルなトランザクションデータに最適なプラットフォームです。
Vector Similarity Search (VSS) は、クラス最高のパフォーマンスと関連性を保証する JVector ライブラリに基づいています。
Apache Cassandra でのベクトル検索は次のように簡単に実行されます。
SELECT content FROM table ORDER BY content_vector ANN OF query_embedding ;
これに関する詳細なドキュメントは、ここ [Apache] (英語) で読むことができます。
この Spring AI ベクトルストアは、最新の RAG アプリケーションで動作し、既存のデータやテーブルの上に後付けできるように設計されています。
ストアは、セマンティック検索、地理的近接検索など、既存のデータベース内の RAG 以外のユースケースにも使用できます。
ストアは、構成に応じて必要に応じてスキーマを自動的に作成または拡張します。スキーマの変更を望まない場合は、disallowSchemaChanges
を使用してストアを構成します。
spring-boot-autoconfigure を使用する場合、Spring Boot 標準に従って、disallowSchemaChanges
はデフォルトで true に設定され、適切なコンストラクターで initializeSchema
ブール値を指定するか、application.properties
ファイルで …initialize-schema=true
を設定することによって、スキーマの作成 / 変更をオプトインする必要があります。
JVector とは何ですか ?
JVector [GitHub] (英語) は、純粋な Java 組み込みベクトル検索エンジンです。
これは、他の HNSW ベクトル類似検索実装と比べて際立っており
アルゴリズムが高速。JVector は、DiskANN や関連研究にヒントを得た最先端のグラフアルゴリズムを使用して、高い再現性と低いレイテンシを実現します。
実装が高速。JVector は Panama SIMD API を使用してインデックスの構築とクエリを高速化します。
メモリ効率に優れています。JVector は積量子化を使用してベクトルを圧縮し、検索中にベクトルをメモリ内に保持できるようにします。(PQ 実装の一部として、SIMD アクセラレーションされた kmeans クラスは、Apache Commons Math のクラスよりも 5x 高速です。)
ディスク対応。JVector のディスクレイアウトは、クエリ時に必要な最小限の IOPS を実行するように設計されています。
同時実行。インデックスビルドは少なくとも 32 スレッドまで直線的に拡張されます。スレッドが 2 倍になると、ビルド時間は半分になります。
増分。インデックスを構築しながらクエリを実行します。ベクトルを追加してから検索結果で見つけられるようになるまでの間に遅延はありません。
簡単に埋め込めます。本番環境で使用するユーザーが簡単に埋め込めるように設計された API です。
前提条件
ドキュメントの埋め込みを計算するための
Embedding
インスタンス。これは通常、Spring Bean として構成されます。いくつかのオプションが利用可能です:Transformers Embedding
- ローカル環境での埋め込みを計算します。デフォルトは ONNX と all-MiniLM-L6-v2 Sentence Transformers 経由です。これで問題なく動作します。OpenAI の Embeddings` を使用する場合は、OpenAI 埋め込みエンドポイントを使用します。OpenAI サインアップ (英語) でアカウントを作成し、API キー (英語) で API キートークンを生成する必要があります。
他にも多くの選択肢があります。
Embeddings API
のドキュメントを参照してください。
バージョン 5.0-beta1 の Apache Cassandra インスタンス
マネージドサービスとして、アストラ DB (英語) は充実したフリーレベルのサービスを提供します。
依存関係
これらの依存関係をプロジェクトに追加します。
Cassandra ベクトルストアのみ
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-cassandra-store</artifactId>
</dependency>
または、RAG アプリケーションに必要なすべてのもの (デフォルトの ONNX 埋め込みモデルを使用する)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-cassandra-store-spring-boot-starter</artifactId>
</dependency>
Spring AI BOM をビルドファイルに追加するには、"依存関係管理" セクションを参照してください。 |
プロパティの構成
Spring Boot 構成で次のプロパティを使用して、Apache Cassandra ベクトルストアをカスタマイズできます。
プロパティ | デフォルト値 |
---|---|
| Spring フレームワーク |
| ai_vector_store |
| false |
| |
| コンテンツ |
| 埋め込み |
| false |
| 16 |
使用方法
Apache Cassandra データベースに接続する CassandraVectorStore インスタンスを作成します。
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
CassandraVectorStoreConfig config = CassandraVectorStoreConfig.builder().build();
return new CassandraVectorStore(config, embeddingModel);
}
デフォルト構成では、 |
Cassandra Java ドライバーは、クラスパス上の |
次に、メインコードでいくつかのドキュメントを作成します。
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("country", "UK", "year", 2020)),
new Document("The World is Big and Salvation Lurks Around the Corner", Map.of()),
new Document("You walk forward facing the past and you turn back toward the future.", Map.of("country", "NL", "year", 2023)));
次に、ドキュメントをベクトルストアに追加します。
vectorStore.add(documents);
最後に、クエリに似たドキュメントを取得します。
List<Document> results = vectorStore.similaritySearch(
SearchRequest.query("Spring").withTopK(5));
すべてがうまくいけば、"Spring AI rocks!!" というテキストを含むドキュメントを取得する必要があります。
類似度のしきい値に基づいて結果を制限することもできます。
List<Document> results = vectorStore.similaritySearch(
SearchRequest.query("Spring").withTopK(5)
.withSimilarityThreshold(0.5d));
メタデータのフィルタリング
CassandraVectorStore でも、汎用的でポータブルなメタデータフィルターを活用できます。メタデータ列は CassandraVectorStoreConfig
で構成する必要があります。
例: 次のいずれかのテキスト式言語を使用できます。
vectorStore.similaritySearch(
SearchRequest.query("The World").withTopK(TOP_K)
.withFilterExpression("country in ['UK', 'NL'] && year >= 2020"));
または、プログラムで DSL という式を使用します。
Filter.Expression f = new FilterExpressionBuilder()
.and(f.in("country", "UK", "NL"), f.gte("year", 2020)).build();
vectorStore.similaritySearch(
SearchRequest.query("The World").withTopK(TOP_K)
.withFilterExpression(f));
ポータブルフィルター式は自動的に CQL クエリ [Apache] (英語) に変換されます。
メタデータ列を検索可能にするには、主キーまたは SAI インデックスのいずれかにする必要があります。主キー以外の列をインデックス化するには、メタデータ列を SchemaColumnTags.INDEXED
で構成します。
高度な例: ベクトルストアは Wikipedia の完全なデータセットの上にあります
次の例は、既存のスキーマでストアを使用する方法を示しています。ここでは、完全なウィキペディアデータセットがベクトル化された状態で付属する github.com/datastax-labs/colbert-wikipedia-data (英語) プロジェクトのスキーマを使用します。
使用方法
まず、Cassandra データベースにスキーマを作成します。
wget https://s.apache.org/colbert-wikipedia-schema-cql -O colbert-wikipedia-schema.cql
cqlsh -f colbert-wikipedia-schema.cql
次にストアを次のように設定します。
@Bean
public CassandraVectorStore store(EmbeddingModel embeddingModel) {
List<SchemaColumn> partitionColumns = List.of(new SchemaColumn("wiki", DataTypes.TEXT),
new SchemaColumn("language", DataTypes.TEXT), new SchemaColumn("title", DataTypes.TEXT));
List<SchemaColumn> clusteringColumns = List.of(new SchemaColumn("chunk_no", DataTypes.INT),
new SchemaColumn("bert_embedding_no", DataTypes.INT));
List<SchemaColumn> extraColumns = List.of(new SchemaColumn("revision", DataTypes.INT),
new SchemaColumn("id", DataTypes.INT));
CassandraVectorStoreConfig conf = CassandraVectorStoreConfig.builder()
.withKeyspaceName("wikidata")
.withTableName("articles")
.withPartitionKeys(partitionColumns)
.withClusteringKeys(clusteringColumns)
.withContentColumnName("body")
.withEmbeddingColumndName("all_minilm_l6_v2_embedding")
.withIndexName("all_minilm_l6_v2_ann")
.disallowSchemaChanges()
.addMetadataColumns(extraColumns)
.withPrimaryKeyTranslator((List<Object> primaryKeys) -> {
// the deliminator used to join fields together into the document's id is arbitary
// here "§¶" is used
if (primaryKeys.isEmpty()) {
return "test§¶0";
}
return format("%s§¶%s", primaryKeys.get(2), primaryKeys.get(3));
})
.withDocumentIdTranslator((id) -> {
String[] parts = id.split("§¶");
String title = parts[0];
int chunk_no = 0 < parts.length ? Integer.parseInt(parts[1]) : 0;
return List.of("simplewiki", "en", title, chunk_no, 0);
})
.build();
return new CassandraVectorStore(conf, embeddingModel());
}
@Bean
public EmbeddingModel embeddingModel() {
// default is ONNX all-MiniLM-L6-v2 which is what we want
return new TransformersEmbeddingModel();
}
完全なウィキペディアデータセット
また、Wikipedia データセット全体をロードしたい場合は、まずこのリンク s.apache.org/simplewiki-sstable-tar (英語) から simplewiki-sstable.tar
をダウンロードしてください。ファイルは数十 GB もあるため、これにはしばらく時間がかかります。
tar -xf simplewiki-sstable.tar -C ${CASSANDRA_DATA}/data/wikidata/articles-*/
nodetool import wikidata articles ${CASSANDRA_DATA}/data/wikidata/articles-*/
このテーブルに既存のデータがある場合は、tar を実行するときに tarball のファイルが既存の sstables を上書きしないことを確認する必要があります。 |
nodetool import の代替案としては、Cassandra を再起動するだけです。 |
インデックスに障害がある場合は、自動的に再構築されます。 |