快速開始
DashText,是向量檢索服務(wù)DashVector推薦使用的稀疏向量編碼器(Sparse Vector Encoder),DashText可通過BM25算法將原始文本轉(zhuǎn)換為稀疏向量(Sparse Vector)表達,通過DashText可大幅度簡化使用DashVector關(guān)鍵詞感知檢索能力。
需要使用您的api-key替換示例中的YOUR_API_KEY、您的Cluster Endpoint替換示例中的YOUR_CLUSTER_ENDPOINT,代碼才能正常運行。
本示例僅對Sparse Vector進行功能演示,請根據(jù)實際情況設(shè)置您的向量維度(可參考文章什么是向量)。簡化起見,本文示例代碼中將向量(Dense Vector)維度設(shè)置為4。
Step1. 創(chuàng)建支持Sparse Vector的Collection
import dashvector
client = dashvector.Client(api_key='YOUR_API_KEY', endpoint='YOUR_CLUSTER_ENDPOINT')
assert client
ret = client.create('hybrid_collection', dimension=4, metric='dotproduct')
assert ret
collection = client.get('hybrid_collection')
assert collection
import com.aliyun.dashvector.DashVectorClient;
import com.aliyun.dashvector.DashVectorCollection;
import com.aliyun.dashvector.models.requests.CreateCollectionRequest;
import com.aliyun.dashvector.models.responses.Response;
import com.aliyun.dashvector.proto.CollectionInfo;
DashVectorClient client =
new DashVectorClient("YOUR_API_KEY", "YOUR_CLUSTER_ENDPOINT");
CreateCollectionRequest request = CreateCollectionRequest.builder()
.name("hybrid_collection")
.dimension(4)
.metric(CollectionInfo.Metric.dotproduct)
.dataType(CollectionInfo.DataType.FLOAT)
.build();
Response<Void> response = client.create(request);
System.out.println(response);
DashVectorCollection collection = client.get("hybrid_collection");
僅內(nèi)積度量(metric='dotproduct'
)支持Sparse Vector功能
Step2. 創(chuàng)建SparseVectorEncoder
使用內(nèi)置Encoder
from dashtext import SparseVectorEncoder
encoder = SparseVectorEncoder.default()
import com.aliyun.dashtext.encoder.SparseVectorEncoder;
SparseVectorEncoder encoder = SparseVectorEncoder.getDefaultInstance();
基于自有語料創(chuàng)建Encoder
from dashtext import SparseVectorEncoder
encoder = SparseVectorEncoder()
# (全部)自有語料
corpus = [
"向量檢索服務(wù)DashVector基于阿里云自研的高效向量引擎Proxima內(nèi)核,提供具備水平拓展能力的云原生、全托管的向量檢索服務(wù)",
"DashVector將其強大的向量管理、向量查詢等多樣化能力,通過簡潔易用的SDK/API接口透出,方便被上層AI應用迅速集成",
"從而為包括大模型生態(tài)、多模態(tài)AI搜索、分子結(jié)構(gòu)分析在內(nèi)的多種應用場景,提供所需的高效向量檢索能力",
"簡單靈活、開箱即用的SDK,使用極簡代碼即可實現(xiàn)向量管理",
"自研向量相似性比對算法,快速高效穩(wěn)定服務(wù)",
"Schema-free設(shè)計,通過Schema實現(xiàn)任意條件下的組合過濾查詢"
]
# 基于自有語料訓練Encoder
encoder.train(corpus)
import com.aliyun.dashtext.encoder.SparseVectorEncoder;
import java.util.*;
SparseVectorEncoder encoder = new SparseVectorEncoder();
//(全部)自有語料
List<String> corpus = Arrays.asList(
"向量檢索服務(wù)DashVector基于阿里云自研的高效向量引擎Proxima內(nèi)核,提供具備水平拓展能力的云原生、全托管的向量檢索服務(wù)",
"DashVector將其強大的向量管理、向量查詢等多樣化能力,通過簡潔易用的SDK/API接口透出,方便被上層AI應用迅速集成",
"從而為包括大模型生態(tài)、多模態(tài)AI搜索、分子結(jié)構(gòu)分析在內(nèi)的多種應用場景,提供所需的高效向量檢索能力",
"簡單靈活、開箱即用的SDK,使用極簡代碼即可實現(xiàn)向量管理",
"自研向量相似性比對算法,快速高效穩(wěn)定服務(wù)",
"Schema-free設(shè)計,通過Schema實現(xiàn)任意條件下的組合過濾查詢"
);
// 基于自有語料訓練Encoder
encoder.train(corpus);
內(nèi)置Encoder可直接使用,無需使用原始語料進行訓練,使用起來更加方便,同時泛化能力較強。但面對原始語料中專業(yè)術(shù)語較多等場景,準確性偏弱
基于自有語料創(chuàng)建Encoder,需要預先根據(jù)(全部)原始語料進行訓練,準確性較高,自有語料創(chuàng)建Encoder具體使用可參考進階使用
用戶需根據(jù)自身業(yè)務(wù)場景和需求來選擇Encoder,對于特定領(lǐng)域(大量專屬詞匯)的場景推薦基于自有語料創(chuàng)建Encoder
Step3. 插入帶有Sparse Vector的Doc
from dashvector import Doc
document = "向量檢索服務(wù)DashVector基于阿里云自研的高效向量引擎Proxima內(nèi)核,提供具備水平拓展能力的云原生、全托管的向量檢索服務(wù)。"
doc_sparse_vector = encoder.encode_documents(document)
print(doc_sparse_vector)
# 基于內(nèi)置Encoder的output:
# {380823393: 0.7262431704356519, 414191989: 0.7262431704356519, 565176162: 0.7262431704356519, 904594806: 0.7262431704356519, 1005505802: 0.7262431704356519, 1169440797: 0.8883757984694465, 1240922502: 0.7262431704356519, 1313971048: 0.7262431704356519, 1317077351: 0.7262431704356519, 1490140460: 0.7262431704356519, 1574737055: 0.7262431704356519, 1760434515: 0.7262431704356519, 2045788977: 0.8414146776926797, 2141666983: 0.7262431704356519, 2509543087: 0.7262431704356519, 3180265193: 0.7262431704356519, 3845702398: 0.7262431704356519, 4106887295: 0.7262431704356519}
collection.insert(Doc(
id='A',
vector=[0.1, 0.2, 0.3, 0.4],
sparse_vector=doc_sparse_vector
))
String document = "向量檢索服務(wù)DashVector基于達摩院自研的高效向量引擎Proxima內(nèi)核,提供具備水平拓展能力的云原生、全托管的向量檢索服務(wù)。";
Map<Long, Float> sparseVector = encoder.encodeDocuments(document);
System.out.println(sparseVector);
// 基于內(nèi)置Encoder的output:
// {380823393: 0.7262431704356519, 414191989: 0.7262431704356519, 565176162: 0.7262431704356519, 904594806: 0.7262431704356519, 1005505802: 0.7262431704356519, 1169440797: 0.8883757984694465, 1240922502: 0.7262431704356519, 1313971048: 0.7262431704356519, 1317077351: 0.7262431704356519, 1490140460: 0.7262431704356519, 1574737055: 0.7262431704356519, 1760434515: 0.7262431704356519, 2045788977: 0.8414146776926797, 2141666983: 0.7262431704356519, 2509543087: 0.7262431704356519, 3180265193: 0.7262431704356519, 3845702398: 0.7262431704356519, 4106887295: 0.7262431704356519}
Vector vector = Vector.builder().value(Arrays.asList(0.1f, 0.2f, 0.3f, 0.4f)).build();
// 構(gòu)建帶有Sparse Vector的Doc
Doc doc = Doc.builder()
.id("28")
.sparseVector(sparseVector)
.vector(vector)
.build();
// 插入帶有Sparse Vector的Doc
Response<Void> response = collection.insert(InsertDocRequest.builder().doc(doc).build());
Step4. 關(guān)鍵詞感知的向量檢索
query = "什么是向量檢索服務(wù)?"
sparse_vector = encoder.encode_queries(query)
print(sparse_vector)
# 基于內(nèi)置Encoder的output:
# {1169440797: 0.2947158712590364, 2045788977: 0.7052841287409635}
docs = collection.query(
vector=[0.1, 0.1, 0.1, 0.1],
sparse_vector=sparse_vector
)
String query = "什么是向量檢索服務(wù)?";
Map<Long, Float> sparseVector = encoder.encodeQueries(query);
System.out.println(sparseVector);
// 基于內(nèi)置Encoder的output:
// {1169440797: 0.2947158712590364, 2045788977: 0.7052841287409635}
Vector vector = Vector.builder().value(Arrays.asList(0.1f, 0.2f, 0.3f, 0.4f)).build();
// 構(gòu)建QueryDocRequest
QueryDocRequest request = QueryDocRequest.builder()
.vector(vector)
.sparseVector(sparseVector)
.topk(100)
.includeVector(true)
.build();
Response<List<Doc>> response = collection.query(request);
System.out.println(response);
Step5. 基于權(quán)重的關(guān)鍵詞+語義檢索
from dashtext import combine_dense_and_sparse
query = "什么是向量檢索服務(wù)?"
sparse_vector = encoder.encode_queries(query)
# 權(quán)重因子
alpha = 0.7
dense_vector = [0.1, 0.1, 0.1, 0.1]
scaled_dense_vector, scaled_sparse_vector = combine_dense_and_sparse(dense_vector, sparse_vector, alpha)
docs = collection.query(
vector=scaled_dense_vector,
sparse_vector=scaled_sparse_vector
)
String query = "什么是向量檢索服務(wù)?";
Map<Long, Float> sparseVector = encoder.encodeQueries(query);
System.out.println(sparse_vector);
// 基于內(nèi)置Encoder的output:
// {1169440797: 0.2947158712590364, 2045788977: 0.7052841287409635}
Vector denseVector = Vector.builder().value(Arrays.asList(0.1f, 0.2f, 0.3f, 0.4f)).build();
// 通過alpha因子調(diào)整稠密向量和稀疏向量
float alpha = 0.1;
sparse_vector.forEach((key, value) -> sparse_vector.put(key, value * (1 - alpha)));
denseVector = Vector.builder().value(
denseVector.getValue().stream().map(number -> number.floatValue() * alpha).collect(Collectors.toList())
).build();
// 構(gòu)建QueryDocRequest
QueryDocRequest request = QueryDocRequest.builder()
.vector(denseVector)
.sparseVector(sparseVector)
.topk(100)
.includeVector(true)
.build();
Response<List<Doc>> response = collection.query(request);
System.out.println(response);
參數(shù)alpha是控制稠密向量距離和稀疏向量距離加權(quán)的權(quán)重因子,alpha=0.0表示只采用稀疏向量進行距離度量,alpha=1.0表示只采用稠密向量進行距離度量。
API參考
更多DashText API詳情可參考:
Python SDK:https://pypi.org/project/dashtext/