DashText-快速開始

DashVector發表於2024-10-30

快速開始

DashText,是向量檢索服務DashVector推薦使用的稀疏向量編碼器(Sparse Vector Encoder),DashText可透過BM25演算法將原始文字轉換為稀疏向量(Sparse Vector)表達,透過DashText可大幅度簡化使用DashVector[關鍵詞感知檢索]能力。

說明

  1. 需要使用您的api-key替換示例中的YOUR_API_KEY、您的Cluster Endpoint替換示例中的YOUR_CLUSTER_ENDPOINT,程式碼才能正常執行。

  2. 本示例僅對Sparse Vector進行功能演示,請根據實際情況設定您的向量維度。簡化起見,本文示例程式碼中將向量(Dense Vector)維度設定為4。

Step1. 建立支援Sparse Vector的Collection

Python示例

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

Java示例

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");

重要

僅內積度量(metric='dotproduct')支援Sparse Vector功能

Step2. 建立SparseVectorEncoder

使用內建Encoder

Python示例

from dashtext import SparseVectorEncoder

encoder = SparseVectorEncoder.default()

Java示例

import com.aliyun.dashtext.encoder.SparseVectorEncoder;

SparseVectorEncoder encoder = SparseVectorEncoder.getDefaultInstance();

說明

內建Encoder使用中文Wiki語料進行訓練,採用Jieba進行中文分詞

基於自有語料建立Encoder

Python示例

from dashtext import SparseVectorEncoder

encoder = SparseVectorEncoder()

# (全部)自有語料
corpus = [
    "向量檢索服務DashVector基於阿里雲自研的高效向量引擎Proxima核心,提供具備水平擴充能力的雲原生、全託管的向量檢索服務",
    "DashVector將其強大的向量管理、向量查詢等多樣化能力,透過簡潔易用的SDK/API介面透出,方便被上層AI應用迅速整合",
    "從而為包括大模型生態、多模態AI搜尋、分子結構分析在內的多種應用場景,提供所需的高效向量檢索能力",
    "簡單靈活、開箱即用的SDK,使用極簡程式碼即可實現向量管理",
    "自研向量相似性比對演算法,快速高效穩定服務",
    "Schema-free設計,透過Schema實現任意條件下的組合過濾查詢"
]

# 基於自有語料訓練Encoder
encoder.train(corpus)

Java示例

import com.aliyun.dashtext.encoder.SparseVectorEncoder;
import java.util.*;

SparseVectorEncoder encoder = new SparseVectorEncoder();

//(全部)自有語料
List<String> corpus = Arrays.asList(
  "向量檢索服務DashVector基於阿里雲自研的高效向量引擎Proxima核心,提供具備水平擴充能力的雲原生、全託管的向量檢索服務",
  "DashVector將其強大的向量管理、向量查詢等多樣化能力,透過簡潔易用的SDK/API介面透出,方便被上層AI應用迅速整合",
  "從而為包括大模型生態、多模態AI搜尋、分子結構分析在內的多種應用場景,提供所需的高效向量檢索能力",
  "簡單靈活、開箱即用的SDK,使用極簡程式碼即可實現向量管理",
  "自研向量相似性比對演算法,快速高效穩定服務",
  "Schema-free設計,透過Schema實現任意條件下的組合過濾查詢"
);

// 基於自有語料訓練Encoder
encoder.train(corpus);

說明

  1. 內建Encoder可直接使用,無需使用原始語料進行訓練,使用起來更加方便,同時泛化能力較強。但面對原始語料中專業術語較多等場景,準確性偏弱

  2. 基於自有語料建立Encoder,需要預先根據(全部)原始語料進行訓練,準確性較高,自有語料建立Encoder具體使用可參考進階使用

  3. 使用者需根據自身業務場景和需求來選擇Encoder,對於特定領域(大量專屬詞彙)的場景推薦基於自有語料建立Encoder

Step3. 插入帶有Sparse Vector的Doc

Python示例

from dashvector import Doc

document = "向量檢索服務DashVector基於阿里雲自研的高效向量引擎Proxima核心,提供具備水平擴充能力的雲原生、全託管的向量檢索服務。"
doc_sparse_vector = encoder.encode_documents(document)

print(doc_sparse_vector)
# 基於內建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
))

Java示例

String document = "向量檢索服務DashVector基於達摩院自研的高效向量引擎Proxima核心,提供具備水平擴充能力的雲原生、全託管的向量檢索服務。";
Map<Long, Float> sparseVector = encoder.encodeDocuments(document);

System.out.println(sparseVector);
// 基於內建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();

// 構建帶有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. 關鍵詞感知的向量檢索

Python示例

query = "什麼是向量檢索服務?"
sparse_vector = encoder.encode_queries(query)

print(sparse_vector)
# 基於內建Encoder的output: 
# {1169440797: 0.2947158712590364, 2045788977: 0.7052841287409635}

docs = collection.query(
    vector=[0.1, 0.1, 0.1, 0.1],
    sparse_vector=sparse_vector
)

Java示例

String query = "什麼是向量檢索服務?";

Map<Long, Float> sparseVector = encoder.encodeQueries(query);

System.out.println(sparseVector);
// 基於內建Encoder的output: 
// {1169440797: 0.2947158712590364, 2045788977: 0.7052841287409635}

Vector vector = Vector.builder().value(Arrays.asList(0.1f, 0.2f, 0.3f, 0.4f)).build();
      	
// 構建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. 基於權重的關鍵詞+語義檢索

Python示例

from dashtext import combine_dense_and_sparse

query = "什麼是向量檢索服務?"
sparse_vector = encoder.encode_queries(query)

# 權重因子
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
)

Java示例

String query = "什麼是向量檢索服務?";

Map<Long, Float> sparseVector = encoder.encodeQueries(query);

System.out.println(sparse_vector);
// 基於內建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因子調整稠密向量和稀疏向量
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();

// 構建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);

說明

引數alpha是控制稠密向量距離和稀疏向量距離加權的權重因子,alpha=0.0表示只採用稀疏向量進行距離度量,alpha=1.0表示只採用稠密向量進行距離度量。

API參考

更多DashText API詳情可參考:

  • Python SDK:https://pypi.org/project/dashtext/

相關文章