You need to enable JavaScript to run this app.
导航
Doubao-embedding API 调用指南
最近更新时间:2024.09.10 20:28:27首次发布时间:2024.05.14 23:56:21

Doubao-embedding 是一款由字节跳动研发的语义向量化模型,主要面向向量检索的使用场景,支持中、英双语,最长 4K 上下文长度。目前提供以下版本:

  • text-240715:最高维度向量 2560,支持 512、1024、2048 降维使用。中英文 Retrieval 效果较 text-240515 版本有较大提升,推荐使用该版本。
  • text-240515:最高维度向量 2048,支持 512、1024 降维使用。

API Host

Host:maas-api.ml-platform-cn-beijing.volces.com Region: cn-beijing

API SDK

提供统一 SDK 的接入形式(需要用 ak/sk 进行旁路鉴权,火山鉴权逻辑可以参考

说明
调用前请修改:

  1. 设置环境变量(或在代码中修改):VOLC_ACCESSKEYVOLC_SECRETKEY

  2. 修改调用模型名占位符{YOUR_ENDPOINT_ID}(具体请参考 API Specification

Golang

package main

import (
        "encoding/json"
        "errors"
        "fmt"
        "os"

        api "github.com/volcengine/volc-sdk-golang/service/maas/models/api/v2"
        client "github.com/volcengine/volc-sdk-golang/service/maas/v2"
)

func main() {
        r := client.NewInstance("maas-api.ml-platform-cn-beijing.volces.com", "cn-beijing")

        // fetch ak&sk from environmental variables
        r.SetAccessKey(os.Getenv("VOLC_ACCESSKEY"))
        r.SetSecretKey(os.Getenv("VOLC_SECRETKEY"))

        req := &api.EmbeddingsReq{
                Input: []string{
                        "天很蓝",
                        "海很深",
                },
        }

        endpointId := "{YOUR_ENDPOINT_ID}"
        TestEmbeddings(r, endpointId, req)
}

func TestEmbeddings(r *client.MaaS, endpointId string, req *api.EmbeddingsReq) {
        got, status, err := r.Embeddings(endpointId, req)
        if err != nil {
                errVal := &api.Error{}
                if errors.As(err, &errVal) { // the returned error always type of *api.Error
                        fmt.Printf("meet maas error=%v, status=%d\n", errVal, status)
                }
                return
        }

        answer, _ := json.Marshal(got)
        fmt.Println("embeddings answer", string(answer))
}

Python

import os
from volcengine.maas.v2 import MaasService
from volcengine.maas import MaasException


def test_embeddings(maas, endpoint_id, req):
    try:
        resp = maas.embeddings(endpoint_id, req)
        print(resp)
    except MaasException as e:
        print(e)


if __name__ == '__main__':
    maas = MaasService('maas-api.ml-platform-cn-beijing.volces.com', 'cn-beijing')

    maas.set_ak(os.getenv("VOLC_ACCESSKEY"))
    maas.set_sk(os.getenv("VOLC_SECRETKEY"))

    # document: "https://www.volcengine.com/docs/82379/1099475"
    # embeddings
    embeddingsReq = {
        "input": [
            "天很蓝",
            "海很深"
        ]
    }

    endpoint_id = "{YOUR_ENDPOINT_ID}"
    test_embeddings(maas, endpoint_id, embeddingsReq)

Java

package com.volcengine.example.maas.v2;

import com.volcengine.model.maas.api.v2.*;
import com.volcengine.service.maas.MaasException;
import com.volcengine.service.maas.v2.MaasService;
import com.volcengine.service.maas.v2.impl.MaasServiceImpl;

import java.util.ArrayList;
import java.util.Arrays;

public class EmbeddingsV2Demo {
    public static void main(String[] args) {
        MaasService maasService = new MaasServiceImpl("maas-api.ml-platform-cn-beijing.volces.com", "cn-beijing");

        // fetch ak&sk from environmental variables
        maasService.setAccessKey(System.getenv("VOLC_ACCESSKEY"));
        maasService.setSecretKey(System.getenv("VOLC_SECRETKEY"));

        EmbeddingsReq tReq = new EmbeddingsReq()
                .withInput(new ArrayList<>(Arrays.asList(
                        "天很蓝",
                        "海很深"
                )));

        String endpointId = "${YOUR_ENDPOINT_ID}";
        testEmbeddings(maasService, endpointId, tReq);
    }

    private static void testEmbeddings(MaasService maasService, String endpointId, EmbeddingsReq req) {
        try {
            EmbeddingsResp resp = maasService.embeddings(endpointId, req);
            System.out.println(resp.getObject());
            System.out.println(resp.getData()); //object: object type 恒为embedding,embedding: embedding向量,index: 列表中序号
        } catch (MaasException e) {
            System.out.println("req_id: " + e.getRequestId());
            System.out.println("code: " + e.getCode());
            System.out.println("code_n: " + e.getCodeN());
            System.out.println("message: " + e.getMsg());
            e.printStackTrace();
        }
    }
}

API Specification

Embeddings

主要参考 OpenAIHuggingFace Parameters 记录可选控制参数,具体哪些参数可用依赖模型服务(模型详情页会描述哪些参数可用)

Input

字段类型描述是否必填

input

list

输入给模型的需要向量化的内容。

"input": [
    "天很蓝",
    "海很深"
]

Output

字段子字段类型描述
req_idstring请求 id

data

lis

每个query的向量化结果

{
    "data": [
        {
            "embedding": [
                0.01131823007017374,
                0.009313009679317474,
                ...
                -0.03317729011178017,
                0.00028884236235171556,
                -0.022333964705467224
            ],
            "object": "embedding"
        },
        {
            "embedding": [
                -0.0019542998634278774,
                ...
                -0.03738011419773102,
                -0.025939496234059334,
                -0.037807632237672806
            ],
            "index": 1,
            "object": "embedding"
        }
    ],
    "object": "list",
    "usage": {
        "prompt_tokens": 6,
        "total_tokens": 6
    }
}
  1. embedding: 向量

  2. index: 向量的序号,与query顺序对应

usageobject该请求的用量统计信息。在 stream 模式下,只有最后一个输出片段才会记录 usage 内容。
prompt_tokensinteger输入 prompt 的 token 数量。
completion_tokensinteger模型输出的 token 数量。
total_tokensinteger输入和输出的总的 token 数量。

最佳实践

注意

Doubao-embedding 模型用于检索场景,query 建议必须添加instruction前缀保证检索效果。

import os
import numpy as np
from typing import List
from volcengine.maas import MaasException, ChatRole
from volcengine.maas.v2 import MaasService

maas = MaasService('maas-api.ml-platform-cn-beijing.volces.com', 'cn-beijing')

maas.set_ak(os.getenv("VOLC_ACCESSKEY"))
maas.set_sk(os.getenv("VOLC_SECRETKEY"))

def test_embeddings(maas, endpoint_id, req):
    try:
        resp = maas.embeddings(endpoint_id, req)
        print(resp)
        return resp
    except MaasException as e:
        print(e)

def sliced_norm_l2(vec: List[float], dim=2048) -> List[float]:
    # dim 取值 512,1024,2048
    norm = float(np.linalg.norm(vec[ :dim]))
    return [v / norm for v in vec[ :dim]]
    

if __name__ == '__main__':
    #  Doubao-embedding模型用于检索场景,query建议必须添加如下instruction前缀保证检索效果
    query_instruction = '为这个句子生成表示以用于检索相关文章:'
    query = "天是什么颜色?"
    # 向量索引的 document 则不添加 instruction
    document = "天空呈现颜色主要与“瑞利散射”现象有关,具体形成过程如下:太阳光是由红、橙、黄、绿、蓝、靛、紫等多种颜色的光混合而成的。大气中存在着无数的气体分子和其他微粒。当太阳光进入地球大气层时,波长较长的红光、橙光、黄光能穿透大气层,直接射到地面,而波长较短的蓝、紫、靛等色光,很容易被悬浮在空气中的微粒阻挡,从而使光线散射向四方。其中蓝光波长较短,散射作用更强,因此我们眼睛看到的天空主要呈现蓝色。在一些特殊情况下,如傍晚或早晨,阳光斜射角度大,通过大气层的路径较长,蓝光等短波长光被散射得更多,而红光等长波长光散射损失较少,这时天空可能会呈现橙红色等其他颜色。"
    
    req = {
        "input": [
            query_instruction + query, # query text
            document, # document text
        ]
    }

    resp = test_embeddings(maas, endpoint_id="ep-xxx-xxx", req=req) # endpoint 使用方舟 2.0 模型接入
    embeddings = [item["embedding"] for item in resp.data]
    query_doc_relevance_score_2048d = np.matmul(
        sliced_norm_l2(embeddings[0], 2048), # query embedding
        sliced_norm_l2(embeddings[1], 2048)  # document embedding
    )
    query_doc_relevance_score_1024d = np.matmul(
        sliced_norm_l2(embeddings[0], 1024), # query embedding,压缩维度
        sliced_norm_l2(embeddings[1], 1024)  # document embedding,压缩维度
    )
    query_doc_relevance_score_512d = np.matmul(
        sliced_norm_l2(embeddings[0], 512), # query embedding,压缩维度
        sliced_norm_l2(embeddings[1], 512)  # document embedding,压缩维度
    )
    print(f"2048 dim relevance score: {query_doc_relevance_score_2048d:6f}")
    print(f"1024 dim relevance score: {query_doc_relevance_score_1024d:6f}")
    print(f" 512 dim relevance score: {query_doc_relevance_score_512d:6f}")
    # 裁剪维度越低,不同内容的区分度越低,检索的准确率、召回率、NDCG 都会变差