Pinecone.netは、Pinecone Vectorデータベース用の本格的なC#ライブラリです。
これは、C#とF#のPineconeのファーストクラスのサポートを提供するコミュニティライブラリです。
dotnet add package Pinecone.NETまたはInstall-Package Pinecone.NET追加します
インデックスの操作
using Pinecone ;
// Initialize the client with your API key
using var pinecone = new PineconeClient ( "your-api-key" ) ;
// List all indexes
var indexes = await pinecone . ListIndexes ( ) ;
// Create a new index if it doesn't exist
var indexName = "myIndex" ;
if ( ! indexes . Contains ( indexName ) )
{
await pinecone . CreateServerlessIndex ( indexName , 1536 , Metric . Cosine , "aws" , "us-east-1" ) ;
}
// Get the Pinecone index by name (uses REST by default).
// The index client is thread-safe, consider caching and/or
// injecting it as a singleton into your DI container.
using var index = await pinecone . GetIndex ( indexName ) ;
// Configure an index
await pinecone . ConfigureIndex ( indexName , replicas : 2 , podType : "p2" ) ;
// Delete an index
await pinecone . DeleteIndex ( indexName ) ;ベクターを使用します
// Assuming you have an instance of `index`
// Create and upsert vectors
var vectors = new [ ]
{
new Vector
{
Id = "vector1" ,
Values = new float [ ] { 0.1f , 0.2f , 0.3f , .. . } ,
Metadata = new MetadataMap
{
[ "genre" ] = "horror" ,
[ "duration" ] = 120
}
}
} ;
await index . Upsert ( vectors ) ;
// Fetch vectors by IDs
var fetched = await index . Fetch ( [ "vector1" ] ) ;
// Query scored vectors by ID
var scored = await index . Query ( "vector1" , topK : 10 ) ;
// Query scored vectors by a new, previously unseen vector
var vector = new [ ] { 0.1f , 0.2f , 0.3f , .. . } ;
var scored = await index . Query ( vector , topK : 10 ) ;
// Query scored vectors by ID with metadata filter
var filter = new MetadataMap
{
[ "genre" ] = new MetadataMap
{
[ "$in" ] = new [ ] { "documentary" , "action" }
}
} ;
var scored = await index . Query ( "birds" , topK : 10 , filter ) ;
// Delete vectors by vector IDs
await index . Delete ( new [ ] { "vector1" } ) ;
// Delete vectors by metadata filter
await index . Delete ( new MetadataMap
{
[ "genre" ] = new MetadataMap
{
[ "$in" ] = new [ ] { "documentary" , "action" }
}
} ) ;
// Delete all vectors in the index
await index . DeleteAll ( ) ;コレクションを操作します
using Pinecone ;
// Assuming you have an instance of `PineconeClient` named `pinecone`
// List all collections
var collections = await pinecone . ListCollections ( ) ;
// Create a new collection
await pinecone . CreateCollection ( "myCollection" , "myIndex" ) ;
// Describe a collection
var details = await pinecone . DescribeCollection ( "myCollection" ) ;
// Delete a collection
await pinecone . DeleteCollection ( "myCollection" ) ; バッチ付きパラレルアップサートの障害から回復します
// Upsert with recovery from up to three failures on batched parallel upsert.
//
// The parallelization is done automatically by the client based on the vector
// dimension and the number of vectors to upsert. It aims to keep the individual
// request size below Pinecone's 2MiB limit with some safety margin for metadata.
// This behavior can be further controlled by calling the 'Upsert' overload with
// custom values for 'batchSize' and 'parallelism' parameters.
//
// This is not the most efficient implementation in terms of allocations in
// GC pause frequency sensitive scenarios, but is perfectly acceptable
// for pretty much all regular back-end applications.
// Assuming there is an instance of 'index' available
// Generate 25k random vectors
var vectors = Enumerable
. Range ( 0 , 25_000 )
. Select ( _ => new Vector
{
Id = Guid . NewGuid ( ) . ToString ( ) ,
Values = Enumerable
. Range ( 0 , 1536 )
. Select ( _ => Random . Shared . NextSingle ( ) )
. ToArray ( )
} )
. ToArray ( ) ;
// Specify the retry limit we are okay with
var retries = 3 ;
while ( true )
{
try
{
// Perform the upsert
await index . Upsert ( vectors ) ;
// If no exception is thrown, break out of the retry loop
break ;
}
catch ( ParallelUpsertException e ) when ( retries -- > 0 )
{
// Create a hash set to efficiently filter out the failed vectors
var filter = e . FailedBatchVectorIds . ToHashSet ( ) ;
// Filter out the failed vectors from the batch and assign them to
// the 'vectors' variable consumed by 'Upsert' operation above
vectors = vectors . Where ( v => filter . Contains ( v . Id ) ) . ToArray ( ) ;
Console . WriteLine ( $ "Retrying upsert due to error: { e . Message } " ) ;
}
}同様のアプローチを使用して、他のストリーミングまたはバッチ操作から回復できます。
vectortypes.csのListOperationException 、 ParallelFetchException 、およびParallelDeleteException参照してください。
デフォルトでは、 RestTransportをお勧めします。以下の特定のシナリオの詳細な説明を見つけてください。
GrpcTransport 、低〜中程度のスループットシナリオの下で大きなベクトルを使用する場合、ネットワークトラフィックを削減するための実行可能な代替手段です。
Protobufは、よりコンパクトな方法でベクトルをエンコードするため、高次元ベクトル(1536-3072+)、リクエストの並行性の低い方、および通常は小さなバッテのベクトルをupSertまたはFethのベクトルを備えている場合、ユースケースのGrpcTransport検討する価値があります。
理論的には、ネットワークトラフィックの減少によりGrpcTransportで低い並行性のスループットが高くなる可能性がありますが、複数の要求を並行して単純に発送するのはどれほど些細なことであるか(およびFetch 、 Upsert 、 Delete自動的に行うという事実)は、このアプローチの利点が制限される可能性が高いです。
執筆時点では、PineconeのHTTP/2スタックは、単一のHTTP/2接続ごとに1つまたは数の並行ストリームを許可するように構成されています。
HTTP/2はGRPCには必須であるため、これにより、高い並行性シナリオの下でGRPCチャネルを介して重要なリクエストを引き起こし、スループットの天井が低いGrpcTransportのスケーラビリティが低下します。
この制限に気付いていないユーザーは、アプリケーションノードごとにユーザー数が増加している場合、および/または予想よりもはるかに低いUpsertおよびFetch Sultputの場合、 Fetch操作が予期しないレイテンシーの増加を経験する可能性があります。
Pinecone.NET 、クライアント側のロードバランシング(DNSレコードベース)を利用するようにGRPCチャネルを構成することにより、この問題を部分的に軽減し、複数のサブチャネルを使用します(DNSクエリで返される現在3つあります)。また、基礎となるSocketsHttpHandlerにエンドポイントごとに複数のHTTP/2接続を使用することもできますが、現在のGRPC実装はこれを適切に利用していないようです。
上記は、ロードテスト下でのクライアントの動作の観察であり、PineconeのコミュニティフォーラムWRTスケーラビリティでのユーザーレポートで示されているように、追加のインフラストラクチャ要因が機能している可能性があります。
高負荷シナリオでGRPCトランスポートをまだ使用したい専門家ユーザーは、このシンプルなコミュニティがサポートするライブラリの範囲外のさらなるアクションアイテムを探索したい場合があります。
定期的なユーザーは、特定の環境でのGrpcTransportの評価がより良い結果をもたらしない限り、代わりに、ハイスループットおよび/または高い並行性シナリオにRestTransportを使用することをお勧めします。
現在のところ、 RestTransportとSystem.Text.Jsonは、シリアル化に使用するために使用します。GRPCTransportおよびProtobuf GrpcTransportもメモリ効率が高いようです。これはGRPCの固有の制限ではなく、 grpc-dotnetの現在の実装の結果です。 System.Text.Jsonは、割り当てトラフィックに関して大幅に最適化されており、軽量と重い負荷の両方で保持されたメモリ使用量が大幅に低下します。 grpc-dotnet実装の現在の状態を考えると、近い将来にこれが変更されるとは予想していません。ほとんどのアプリケーションにとっては「十分に良い」ですが、負荷の下での持続的なヒープサイズの違いは、これを明示的に述べることを保証するのに十分なほど重要です。
Pinecone.NET 、ベクトル値を保存するためにベクトル値を保存するrepeect-Copy構造/ RepeatedField<float>をすでに実行していることに注意してください。ただし、プレーンSystem.Text.Jsonを使用することの利点を相殺するには十分ではありません。
貢献は大歓迎です!問題やPRを自由に開いてください。