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+), 낮은 요청 동시성 및 일반적으로 작은 박스에서 벡터가 부여되거나 페치하는 경우 사용 사례에 대한 GrpcTransport 고려할 가치가 있습니다.
이론적으로, 네트워크 트래픽 감소로 인해 GrpcTransport 에서 동시 동시성 처리량이 낮을 수 있지만, 여러 요청을 병렬로 단순히 파견하는 것이 얼마나 사소한 지 (그리고 Fetch , Upsert 및 Delete 사실)이 접근법의 이점이 제한 될 가능성이 높습니다.
글을 쓰는 시점에서 Pinecone의 HTTP/2 스택은 단일 HTTP/2 연결 당 동시 스트림을 거의 또는 단 1 개만 허용하도록 구성됩니다.
HTTP/2는 GRPC에 필수적이므로 동시성 시나리오가 높은 시나리오에서 GRPC 채널을 통한 상당한 요청 대기열이 발생하여 처리량이 낮은 천장으로 GrpcTransport 의 확장 성이 좋지 않습니다.
이 제한을 알지 못하는 사용자는 애플리케이션 노드 당 사용자 수 증가 하에서 쿼리 작업의 예상치 못한 대기 시간 증가를 경험할 수 있으며/또는 예상되는 Upsert보다 훨씬 낮은 Upsert 및 Fetch 처리량보다 훨씬 낮은 Upsert 및 Fetch Operation을 수동으로 지정할 때에도 처리량이 훨씬 낮습니다.
Pinecone.NET GRPC 채널을 구성하여 클라이언트 측로드 밸런싱 (DNS 레코드 기반)을 활용하여 여러 하위 채널 (현재 DNS 쿼리에서 반환 된 3 개가 있음)을 사용하여 다른 클라이언트보다 더 나은 처리량을 제공 할 것으로 예상됩니다. 또한 기본 SocketsHttpHandler 에 대한 엔드 포인트 당 여러 HTTP/2 연결을 사용할 수 있지만 현재 GRPC 구현은이를 제대로 활용하지 못하는 것 같습니다.
위의 내용은로드 테스트 하에서 클라이언트 동작을 관찰하는 것이며 추가 인프라 요소는 다른 구현에서 Pinecone의 Community Forum WRT 확장 성의 사용자 보고서에 의해 표시 될 수 있습니다.
고재 시나리오에서 여전히 GRPC 전송을 사용하려는 전문가 사용자는이 간단한 커뮤니티 지원 라이브러리의 범위를 벗어난 추가 작업 항목을 탐색 할 수 있습니다.
특정 환경에서 GrpcTransport 를 평가하는 것이 더 나은 결과를 얻지 않는 한 일반 사용자는 대신 고 처리량 및/또는 높은 동시성 시나리오에 RestTransport 사용하는 것이 좋습니다.
현재로서는 RestTransport 및 System.Text.Json 직렬화에 사용하는 것이 GrpcTransport 및 Protobuf 보다 메모리 효율적으로 보입니다. 이는 GRPC의 고유 한 제한이 아니라 grpc-dotnet 의 현재 구현의 결과입니다. System.Text.Json 은 할당 트래픽과 관련하여 크게 최적화되어 있으며 가벼운 부하와 무거운 부하 모두에서 지속적인 메모리 사용량이 상당히 낮아집니다. grpc-dotnet 구현의 현재 상태를 고려할 때, 나는 이것이 가까운 시일 내에 변화를 기대하지 않습니다. 대부분의 응용 분야에서는 "충분히 양호"이지만 부하의 지속적인 힙 크기 차이는이를 명시 적으로 진술 할 수있을 정도로 중요합니다.
Pinecone.NET 이미 할당 압력을 완화하기 위해 벡터 값을 저장하는 RepeatedField<float> 의 제로 카피 구성/읽기를 수행하지만 일반 System.Text.Json Serialization을 사용하는 이점을 상쇄하는 것만으로는 충분하지 않습니다.
기부금을 환영합니다! 문제 나 PR을 열어주십시오.