Embedding

Embedding(也称为嵌入)是将文本、图片或音视频等数据转化为向量(数字序列)的一种方法。向量的特点在于可以用数学方式表示数据间的关系,向量之间的距离代表数据的相关性。距离越小,相关性越高;距离越大,相关性越低。

应用场景

  • 推荐:根据输入数据推荐相关信息条目。例如,根据用户购买历史和浏览记录推荐相关商品。

  • 聚类:按相关性对输入数据进行分类。例如,将海量新闻按主题归类为科技、体育、娱乐等。

  • 搜索:将搜索结果按照与输入数据的相关性进行排序。例如,文本向量模型可以根据用户搜索词语返回相关网页,多模态向量模型可以实现以文搜图。

  • 异常检测:识别出相关性较小的异常值。例如,从大量交易记录中识别出异常交易模式。

支持的模型

通用文本向量

向量维度指的是向量中包含的元素数量。例如,一个 1024 维的向量包含 1024 个数值。维度越高,向量能表示的信息就越丰富,从而更细致地捕捉文本的特性。

模型名称

向量维度

最大行数

单行最大处理Token

支持语种

单价(每千输入Token)

免费额度(注)

text-embedding-v3

1,024(默认)、768512

6

8,192

中文、英语、西班牙语、法语、葡萄牙语、印尼语、日语、韩语、德语、俄罗斯语等50+主流语种

0.0007

50Token

有效期:百炼开通后180天内

text-embedding-v2

1,536

25

2,048

中文、英语、西班牙语、法语、葡萄牙语、印尼语、日语、韩语、德语、俄罗斯语

text-embedding-v1

中文、英语、西班牙语、法语、葡萄牙语、印尼语

text-embedding-async-v2

100,000

中文、英语、西班牙语、法语、葡萄牙语、印尼语、日语、韩语、德语、俄罗斯语

2000Token

有效期:百炼开通后180天内

text-embedding-async-v1

中文、英语、西班牙语、法语、葡萄牙语、印尼语

模型升级概述

  1. text-embedding-v2

    • 语种扩充:新增对日语、韩语、德语、俄罗斯语的文本向量化能力。

    • 效果提升:优化了预训练模型和SFT策略,提升了整体效果,公开数据评测结果显示有显著改进。

  2. text-embedding-v3

    • 语种扩充:支持意大利语、波兰语、越南语、泰语等语种,语种数量增加至50余种。

    • 输入长度扩展:最大输入长度从2048 Token扩展至8192 Token。

    • 连续向量维度自定义:允许用户选择512、7681024维度,默认维度改为1024。

    • 不再区分Query/Document类型:简化输入,text_type参数不再需要指定文本类型。

    • Sparse向量支持:支持在接口中指定输出稠密向量和离散向量。

    • 效果提升:进一步优化预训练模型和SFT策略,提升整体效果,公开数据评测结果显示效果更佳。

v1、v2、v3模型的效果数据

模型

MTEB

MTEB(Retrieval task)

CMTEB

CMTEB (Retrieval task)

text-embedding-v1

58.30

45.47

59.84

56.59

text-embedding-v2

60.13

49.49

62.17

62.78

text-embedding-v3(512维度)

62.11

54.30

66.81

71.88

text-embedding-v3(768维度)

62.43

54.74

67.90

72.29

text-embedding-v3(1024维度)

63.39

55.41

68.92

73.23

多模态向量

模型根据用户的输入生成连续向量,这些输入可以是文本、图片或视频,文件格式详情请参照调用限制。适用于视频分类、图像分类、图文检索等任务场景。

模型名称

数据类型

向量维度

单价

免费额度(注)

限流

multimodal-embedding-v1

float(32)

1,024

免费试用,并将于202511日转为付费制

无加权条目数限制

有效期至:202511

每分钟调用限制(RPM):120

选型建议

首选模型

对于涉及图像与视频的多模态向量分析,请使用multimodal-embedding-v1

对于纯文本的向量分析,建议选择 text-embedding-v3。该版本在语种支持、输入长度和向量维度自定义化等方面进行了全面升级,适用于大部分场景:

  • 单行文本处理长度:最大单行输入长度扩展至 8192 Token。

  • 更多语种支持:覆盖 50+ 种语言。

  • 灵活的向量维度选择:提供 512、768 和 1024 三种维度选择,维度越高,语义表达精度越高,下游任务的计算/存储成本也相应增加。

  • 多样化输出选项:支持稠密向量(dense)和离散向量(sparse),满足不同应用场景需求:

    • 稠密向量:能够更加有效地捕捉文本的语义特征,适用于常规检索和语义匹配场景。

    • 离散向量:降低计算复杂度和存储成本,适用于存储资源有限或需高效语义匹配场景。

对于通过字符串输入的情况,模型会将整个字符串视为单行,输入长度的上限为 8192 Token。如果字符串内容超过此限制,可以使用以下方法调整输入格式:

  1. 字符串列表输入:将输入内容拆分为多个部分并生成一个字符串列表。需确保以下条件:

    • 列表中的元素数量不超过 6 个

    • 每个元素的长度需在 8192 Token 内

  2. 文件上传:将输入的字符串内容整合至文件,通过文件方式上传。需确保以下条件:

    • 文件的总行数不超过 6 行

    • 每行长度在 8192 Token 内

选择 async 版本(大批量文本或高并发场景)

对于需要高并发或大批量文本处理的场景,建议选择 text-embedding-async-v1text-embedding-async-v2

  • 大批量文本输入:async 版本单次可处理高达100,000 行的文本信息,每一行文本都会生成一个单独的向量,非常适合大规模数据预处理、批量建库或更新任务。

  • 版本选择建议:async 版本适用于建库/更新库等高批量计算场景,但会将结果文件以URL形式返回,用户需要额外步骤下载并处理结果文件,这可能不适用于实时性要求较高的任务。建议根据功能需求选择 v1 或 v2 的 async 版本,且优先选择与现有版本兼容的 async 版本。

快速入门

您需要已获取API Key配置API Key到环境变量。如果通过OpenAI SDKDashScope SDK进行调用,还需要安装SDK

通用文本向量快速入门

输入字符串

OpenAI兼容调用

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),  # 如果您没有配置环境变量,请在此处用您的API Key进行替换
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"  # 填写百炼服务的base_url
)

completion = client.embeddings.create(
    model="text-embedding-v3",
    input='衣服的质量杠杠的,很漂亮,不枉我等了这么久啊,喜欢,以后还来这里买',
    dimensions=1024,
    encoding_format="float"
)

print(completion.model_dump_json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.dashscope.utils.JsonUtils;

public final class Main {
    public static void main(String[] args) {
        /** 从环境变量中获取 API Key,如果未配置,请直接替换为您的 API Key*/
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        if (apiKey == null) {
            System.out.println("DASHSCOPE_API_KEY not found in environment variables");
            return;
        }
        String baseUrl = "https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings";
        HttpClient client = HttpClient.newHttpClient();

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "text-embedding-v3");
        requestBody.put("input", "衣服的质量杠杠的,很漂亮,不枉我等了这么久啊,喜欢,以后还来这里买");
        requestBody.put("dimensions", 1024);
        requestBody.put("encoding_format", "float");

        try {
            String requestBodyString = JsonUtils.toJson(requestBody);
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(baseUrl))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + apiKey)
                    .POST(HttpRequest.BodyPublishers.ofString(requestBodyString))
                    .build();
                    
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() == 200) {
                System.out.println("Response: " + response.body());
            } else {
                System.out.printf("Failed to retrieve response, status code: %d, response: %s%n", response.statusCode(), response.body());
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}
curl --location 'https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "text-embedding-v3",
    "input": "衣服的质量杠杠的,很漂亮,不枉我等了这么久啊,喜欢,以后还来这里买",  
    "dimension": "1024",  
    "encoding_format": "float"
}'

DashScope调用

在使用 Java 并通过 DashScope 调用 Embedding 模型时,当前仅支持对text-embedding-v1text-embedding-v2模型的调用。
import dashscope
from http import HTTPStatus

resp = dashscope.TextEmbedding.call(
    model=dashscope.TextEmbedding.Models.text_embedding_v3,
    input='衣服的质量杠杠的,很漂亮,不枉我等了这么久啊,喜欢,以后还来这里买',
    dimension=1024
    output_type="dense&sparse"
)

print(resp) if resp.status_code == HTTPStatus.OK else print(resp)
import java.util.Arrays;
import java.util.concurrent.Semaphore;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.embeddings.TextEmbedding;
import com.alibaba.dashscope.embeddings.TextEmbeddingParam;
import com.alibaba.dashscope.embeddings.TextEmbeddingResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;

public final class Main {
    public static void basicCall() throws ApiException, NoApiKeyException{
        TextEmbeddingParam param = TextEmbeddingParam
        .builder()
        .model(TextEmbedding.Models.TEXT_EMBEDDING_V1)
        .texts(Arrays.asList("风急天高猿啸哀", "渚清沙白鸟飞回", "无边落木萧萧下", "不尽长江滚滚来")).build();
        TextEmbedding textEmbedding = new TextEmbedding();
        TextEmbeddingResult result = textEmbedding.call(param);
        System.out.println(result);
    }
  
    public static void callWithCallback() throws ApiException, NoApiKeyException, InterruptedException{
        TextEmbeddingParam param = TextEmbeddingParam
        .builder()
        .model(TextEmbedding.Models.TEXT_EMBEDDING_V1)
        .texts(Arrays.asList("风急天高猿啸哀", "渚清沙白鸟飞回", "无边落木萧萧下", "不尽长江滚滚来")).build();
        TextEmbedding textEmbedding = new TextEmbedding();
        Semaphore sem = new Semaphore(0);
        textEmbedding.call(param, new ResultCallback<TextEmbeddingResult>() {

          @Override
          public void onEvent(TextEmbeddingResult message) {
            System.out.println(message);
          }
          @Override
          public void onComplete(){
            sem.release();
          }

          @Override
          public void onError(Exception err){
            System.out.println(err.getMessage());
            err.printStackTrace();
            sem.release();
          }
          
        });
        sem.acquire();
    }

  public static void main(String[] args){
    try{
      callWithCallback();
    }catch(ApiException|NoApiKeyException|InterruptedException e){
      e.printStackTrace();
      System.out.println(e);

    }
      try {
        basicCall();
    } catch (ApiException | NoApiKeyException e) {
        System.out.println(e.getMessage());
    }
    System.exit(0);
  }
}
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/embeddings/text-embedding/text-embedding' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "text-embedding-v3",
    "input": {
        "texts": [
        "衣服的质量杠杠的,很漂亮,不枉我等了这么久啊,喜欢,以后还来这里买"
        ]
    },
    "parameters": {
    	"dimension": 1024
    }
}'

输入字符串列表

OpenAI兼容调用

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),  # 如果您没有配置环境变量,请在此处用您的API Key进行替换
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"  # 填写百炼服务的base_url
)

completion = client.embeddings.create(
    model="text-embedding-v3",
    input=['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来'],
    encoding_format="float"
)

print(completion.model_dump_json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Arrays;
import com.alibaba.dashscope.utils.JsonUtils;

public final class Main {
    public static void main(String[] args) {
        /** 从环境变量中获取 API Key,如果未配置,请直接替换为您的 API Key*/
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        if (apiKey == null) {
            System.out.println("DASHSCOPE_API_KEY not found in environment variables");
            return;
        }
        String baseUrl = "https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings";
        HttpClient client = HttpClient.newHttpClient();
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "text-embedding-v3");
        List<String> inputList = Arrays.asList("风急天高猿啸哀", "渚清沙白鸟飞回", "无边落木萧萧下", "不尽长江滚滚来");
        requestBody.put("input", inputList);
        requestBody.put("encoding_format", "float");

        try {
            /** 将请求体转换为 JSON 字符串*/
            String requestBodyString = JsonUtils.toJson(requestBody);

            /**构建 HTTP 请求*/
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(baseUrl))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + apiKey)
                    .POST(HttpRequest.BodyPublishers.ofString(requestBodyString))
                    .build();

            /**发送请求并接收响应*/
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() == 200) {
                System.out.println("Response: " + response.body());
            } else {
                System.out.printf("Failed to retrieve response, status code: %d, response: %s%n", response.statusCode(), response.body());
            }
        } catch (Exception e) {
            /** 捕获并打印异常*/
            System.err.println("Error: " + e.getMessage());
        }
    }
}
curl --location 'https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "text-embedding-v3",
    "input": [
        "风急天高猿啸哀",
        "渚清沙白鸟飞回", 
        "无边落木萧萧下", 
        "不尽长江滚滚来"
        ],
    "encoding_format": "float"
}'

DashScope调用

在使用 Java 并通过 DashScope 调用 Embedding 模型时,当前仅支持对text-embedding-v1text-embedding-v2模型的调用。
import dashscope
from http import HTTPStatus

DASHSCOPE_MAX_BATCH_SIZE = 25

inputs = ['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']

result = None
batch_counter = 0
for i in range(0, len(inputs), DASHSCOPE_MAX_BATCH_SIZE):
    batch = inputs[i:i + DASHSCOPE_MAX_BATCH_SIZE]
    resp = dashscope.TextEmbedding.call(
        model=dashscope.TextEmbedding.Models.text_embedding_v3,
        input=batch,
        dimension=1024
    )
    if resp.status_code == HTTPStatus.OK:
        if result is None:
            result = resp
        else:
            for emb in resp.output['embeddings']:
                emb['text_index'] += batch_counter
                result.output['embeddings'].append(emb)
            result.usage['total_tokens'] += resp.usage['total_tokens']
    else:
        print(resp)
    batch_counter += len(batch)

print(result)
import java.util.Arrays;
import java.util.List;
import com.alibaba.dashscope.embeddings.TextEmbedding;
import com.alibaba.dashscope.embeddings.TextEmbeddingParam;
import com.alibaba.dashscope.embeddings.TextEmbeddingResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;

public final class Main {
    private static final int DASHSCOPE_MAX_BATCH_SIZE = 25;

    public static void main(String[] args) {
        List<String> inputs = Arrays.asList(
                "风急天高猿啸哀",
                "渚清沙白鸟飞回",
                "无边落木萧萧下",
                "不尽长江滚滚来"
        );

        TextEmbeddingResult result = null;
        int batchCounter = 0;

        for (int i = 0; i < inputs.size(); i += DASHSCOPE_MAX_BATCH_SIZE) {
            List<String> batch = inputs.subList(i, Math.min(i + DASHSCOPE_MAX_BATCH_SIZE, inputs.size()));
            TextEmbeddingParam param = TextEmbeddingParam.builder()
                    .model(TextEmbedding.Models.TEXT_EMBEDDING_V1)
                    .texts(batch)
                    .build();

            TextEmbedding textEmbedding = new TextEmbedding();
            try {
                TextEmbeddingResult resp = textEmbedding.call(param);
                if (resp != null) {
                    if (result == null) {
                        result = resp;
                    } else {
                        for (var emb : resp.getOutput().getEmbeddings()) {
                            emb.setTextIndex(emb.getTextIndex() + batchCounter);
                            result.getOutput().getEmbeddings().add(emb);
                        }
                        result.getUsage().setTotalTokens(result.getUsage().getTotalTokens() + resp.getUsage().getTotalTokens());
                    }
                } else {
                    System.out.println(resp);
                }
            } catch (ApiException | NoApiKeyException e) {
                e.printStackTrace();
            }
            batchCounter += batch.size();
        }

        System.out.println(result);
    }
}
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/embeddings/text-embedding/text-embedding' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "text-embedding-v3",
    "input": {
        "texts": [
          "风急天高猿啸哀",
          "渚清沙白鸟飞回", 
          "无边落木萧萧下", 
          "不尽长江滚滚来"
        ]
    },
    "parameters": {
    	  "dimension": 1024
    }
}'

输入文件

Embedding模型可以基于您上传的文档进行回复。此处以texts_to_embedding.txt作为示例文件。

OpenAI兼容调用

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),  # 如果您没有配置环境变量,请在此处用您的API Key进行替换
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"  # 填写百炼服务的base_url
)
with open('texts_to_embedding.txt', 'r', encoding='utf-8') as f:
    completion = client.embeddings.create(
        model="text-embedding-v3",
        input=f
    )
print(completion.model_dump_json())
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import com.alibaba.dashscope.utils.JsonUtils;

public class Main {
    public static void main(String[] args) {
        /** 从环境变量中获取 API Key,如果未配置,请直接替换为您的 API Key*/
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        if (apiKey == null) {
            System.out.println("DASHSCOPE_API_KEY not found in environment variables");
            return;
        }
        String baseUrl = "https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings";
        HttpClient client = HttpClient.newHttpClient();

        /** 读取输入文件*/
        StringBuilder inputText = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader("<文件所来自的内容根的路径>"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                inputText.append(line).append("\n");
            }
        } catch (IOException e) {
            System.err.println("Error reading input file: " + e.getMessage());
            return;
        }

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "text-embedding-v3");
        requestBody.put("input", inputText.toString().trim());

        try {
            String requestBodyString = JsonUtils.toJson(requestBody);

            /**构建 HTTP 请求*/
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(baseUrl))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + apiKey)
                    .POST(HttpRequest.BodyPublishers.ofString(requestBodyString))
                    .build();
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() == 200) {
                System.out.println("Response: " + response.body());
            } else {
                System.out.printf("Failed to retrieve response, status code: %d, response: %s%n", response.statusCode(), response.body());
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}
FILE_CONTENT=$(cat texts_to_embedding.txt | jq -Rs .)
curl --location 'https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "text-embedding-v3",
    "input": ['"$FILE_CONTENT"']
}'

DashScope调用

在使用 Java 并通过 DashScope 调用 Embedding 模型时,当前仅支持对text-embedding-v1text-embedding-v2模型的调用。
from http import HTTPStatus
from dashscope import TextEmbedding

with open('texts_to_embedding.txt', 'r', encoding='utf-8') as f:
    resp = TextEmbedding.call(
        model=TextEmbedding.Models.text_embedding_v3,
        input=f
    )

    if resp.status_code == HTTPStatus.OK:
        print(resp)
    else:
        print(resp)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import com.alibaba.dashscope.embeddings.TextEmbedding;
import com.alibaba.dashscope.embeddings.TextEmbeddingParam;
import com.alibaba.dashscope.embeddings.TextEmbeddingResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;

public final class Main {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("<文件所来自的内容根的路径>"))) {
            StringBuilder content = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line).append("\n");
            }

            TextEmbeddingParam param = TextEmbeddingParam.builder()
                    .model(TextEmbedding.Models.TEXT_EMBEDDING_V1)
                    .text(content.toString())
                    .build();

            TextEmbedding textEmbedding = new TextEmbedding();
            TextEmbeddingResult result = textEmbedding.call(param);

            if (result != null) {
                System.out.println(result);
            } else {
                System.out.println("Failed to get embedding: " + result);
            }
        } catch (IOException | ApiException | NoApiKeyException e) {
            e.printStackTrace();
        }
    }
}
FILE_CONTENT=$(cat texts_to_embedding.txt | jq -Rs .)
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/embeddings/text-embedding/text-embedding' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
    "model": "text-embedding-v3",
    "input": {
        "texts": ['"$FILE_CONTENT"']
    }
}'

调用输出

OpenAI兼容调用

{ 
  "data": [
    {
      "embedding": [
        0.0023064255,
        -0.009327292,
        .... 
        -0.0028842222,
      ],
      "index": 0,
      "object": "embedding"
    }
  ],
  "model":"text-embedding-v3",
  "object":"list",
  "usage":{"prompt_tokens":26,"total_tokens":26},
  "id":"f62c2ae7-0906-9758-ab34-47c5764f07e2"
}

DashScope调用

{
    "status_code": 200,
    "request_id": "617b3670-6f9e-9f47-ad57-997ed8aeba6a",
    "code": "",
    "message": "",
    "output": {
        "embeddings": [
            {
                "embedding": [
                    0.09393704682588577,
                    2.4155092239379883,
                    -1.8923076391220093,
                    .,
                    .,
                    .

                ],
                "text_index": 0
            }
        ]
    },
    "usage": {
        "total_tokens": 26
    }
}

多模态向量快速入门

您需要已获取API Key配置API Key到环境变量。如果通过SDK调用,还需要安装DashScope SDK

文本输入

import dashscope
import json
from http import HTTPStatus

text = "通用多模态表征模型示例"
input = [{'text': text}]
resp = dashscope.MultiModalEmbedding.call(
    model="multimodal-embedding-v1",
    input=input
)

if resp.status_code == HTTPStatus.OK:
    print(json.dumps(resp.output, ensure_ascii=False, indent=4))

图片与视频输入

import dashscope
import json
from http import HTTPStatus

image = "https://dashscope.oss-cn-beijing.aliyuncs.com/images/256_1.png"
input = [{'image': image}]
resp = dashscope.MultiModalEmbedding.call(
    model="multimodal-embedding-v1",
    input=input
)

if resp.status_code == HTTPStatus.OK:
    print(json.dumps(resp.output, ensure_ascii=False, indent=4))

输出示例

{
    "status_code": 200,
    "request_id": "23478d14-55c6-98cc-9706-29d23de742fb",
    "code": "",
    "message": "",
    "output": {
        "embeddings": [
            {
                "index": 0,
                "embedding": [
                    -0.0396728515625,
                    0.00650787353515625,
                    -0.0223388671875,
                    ...
                ],
                "type": "image"
            }
        ]
    },
    "usage": {
        "input_tokens": 0,
        "image_count": 1,
        "duration": 0
    }
}

使用示例

实现语义搜索

本实践案例通过文本向量模型获取产品描述对应的向量,然后基于向量,计算评论与产品描述之间的余弦相似度,最终返回与产品描述最相关的评论。

1、导入库包

导入所需的库包,并设置API Key,为后续的数据处理和分析做准备。

import os
import pandas as pd
import numpy as np
from ast import literal_eval
import dashscope
from dashscope import TextEmbedding

# 设置DashScope的API Key
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")

2、读取CSV文件并处理嵌入数据

读取CSV文件fine_food_reviews.csv(其中包含评论和评论对应的向量),转换embedding列的字符串数据为NumPy数组以便后续处理。

# 读取CSV数据
datafile_path = "fine_food_reviews.csv"
df = pd.read_csv(datafile_path)

# 将embedding列的字符串数据转换为NumPy数组
df["embedding"] = df.embedding.apply(literal_eval).apply(np.array)

3、定义文本嵌入的函数

该函数将文本转换为向量,并根据输入类型的不同返回单个向量或向量列表。

# 定义文本嵌入的函数
def generate_embeddings(text):
    rsp = TextEmbedding.call(model=TextEmbedding.Models.text_embedding_v1, input=text)
    embeddings = [record['embedding'] for record in rsp.output['embeddings']]
    return embeddings if isinstance(text, list) else embeddings[0]

4、定义计算余弦相似度函数和搜索评论函数

利用余弦相似度来度量文本之间的相似性,实现了一个基于内容的评论搜索功能。用户可以通过输入产品描述,检索与该产品描述最相关的评论。

# 定义计算余弦相似度函数
def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# 搜索特定产品的评论
def search_reviews(df, product_description, n=3, pprint=True):
    product_embedding = generate_embeddings(product_description)
    df["similarity"] = df.embedding.apply(lambda x: cosine_similarity(x, product_embedding))
    results = (
        df.sort_values("similarity", ascending=False)
        .head(n)
        .combined.str.replace("Title: ", "")
        .str.replace("; Content:", ": ")
    )
    if pprint:
        for r in results:
            print(r[:200])
            print()
    return results

5、测试搜索功能

测试搜索功能,调用search_reviews函数查找与宠物食品相关的评论,并返回2条相似评论。示例代码如下:

results = search_reviews(df, "pet food", n=2)

运行结果为:

This is so good!:  I purchased this after my sister sent a small bag to me in a gift box.  I loved it so much I wanted to find it to buy for myself and keep it around.  I always look on Amazon because

Sweet Perfection:  Not everything in this world is perfect, but this really is the perfect candy. Is delicious!!! I cannot have enough of it!

以下是其他测试代码供参考:

results = search_reviews(df, "delicious beans", n=3)
results = search_reviews(df, "whole wheat pasta", n=3)
results = search_reviews(df, "bad delivery", n=1)
results = search_reviews(df, "spoilt", n=1)

实现语义推荐

1、导入库包、配置API_KEY

导入所需库和模块,并配置DashScopeAPI密钥,以便进行后续的数据处理和分析。

# 导入所需库
import os
import pandas as pd
import pickle
import dashscope
from dashscope import TextEmbedding
import numpy as np

# 设置 DashScope 的 API Key,从环境变量中获取
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")

2、定义embeddings函数

该函数通过DashScopeAPI生成文本嵌入表示。它接受单个字符串或字符串列表,使用TextEmbedding模型处理并提取嵌入向量。如果输入为列表,返回所有嵌入;若为单个字符串,则返回第一个嵌入向量。

# 定义函数:生成文本的嵌入向量(embedding)
def generate_embeddings(text):
    """
    使用 DashScope 的 text-embedding-v3 模型生成输入文本的嵌入向量。
    Args:
        text (str or list): 输入文本字符串或字符串列表。
    Returns:
        list: 如果输入为字符串,返回单个嵌入向量;若输入为列表,返回多个向量。
    """
    rsp = TextEmbedding.call(model=TextEmbedding.Models.text_embedding_v3, input=text)
    # 从 API 响应中提取 embedding
    embeddings = [record['embedding'] for record in rsp.output['embeddings']]
    return embeddings if isinstance(text, list) else embeddings[0]

3、加载数据集并打印前n_examples个样本

加载数据集sampled_file.csv,并打印前n_examples个样本的发布日期与标题。

# 加载数据集
dataset_path = "sampled_file.csv"  # 数据集路径
df = pd.read_csv(dataset_path)  # 读取CSV文件到 DataFrame
n_examples = 5  # 设置展示的示例数量

# 展示前 n_examples 个样本的发布日期与标题
print("展示数据集中的前几个样本:")
for idx, row in df.head(n_examples).iterrows():
    print("")
    print(f"发布日期: {row['publish_date']}")
    print(f"标题: {row['headline_text']}")

4、设置和加载embedding缓存,定义获取embedding的函数

设置和加载嵌入缓存,以提高推荐系统等任务中嵌入向量的处理效率。为了避免在调用模型进行向量化时产生额外费用,可以将已完成向量化并的向量缓存文件存放在项目目录中。

recommendations_embeddings_cache.pk

# 设置嵌入缓存路径(避免重复计算)
embedding_cache_path = "recommendations_embeddings_cache.pkl"

# 尝试加载已缓存的嵌入结果,若无缓存则初始化一个空字典
try:
    embedding_cache = pd.read_pickle(embedding_cache_path)
except FileNotFoundError:
    embedding_cache = {}

# 定义函数:通过缓存机制获取文本的嵌入向量
def embedding_from_string(
    string: str,
    embedding_cache=embedding_cache
) -> list:
    """
    获取给定文本的嵌入向量,使用缓存机制避免重复计算。
    Args:
        string (str): 输入文本字符串。
        embedding_cache (dict): 嵌入缓存字典。
    Returns:
        list: 生成的嵌入向量。
    """
    if string not in embedding_cache.keys():  # 如果缓存中不存在该文本
        embedding_cache[string] = generate_embeddings(string)  # 生成并缓存嵌入
        # 保存缓存到文件
        with open(embedding_cache_path, "wb") as embedding_cache_file:
            pickle.dump(embedding_cache, embedding_cache_file)
    return embedding_cache[string]

5、计算示例字符串的embedding

从数据帧中提取描述列的第一个字符串,并计算其嵌入表示,最后输出前10个元素。

# 计算示例字符串的嵌入向量
example_string = df["headline_text"].values[0]  # 选取数据集中的第一个文本
print(f"\n示例文本: {example_string}")
example_embedding = embedding_from_string(example_string)  # 获取嵌入
print(f"\n示例文本的嵌入向量(前10维): {example_embedding[:10]}...")
print("\n")

6、定义推荐函数

通过计算字符串的embedding向量,并基于余弦相似度的距离,找出与给定字符串最相似的k个字符串后输出这些字符串及其相似度距离。

# 定义推荐函数:输出与给定文本最相似的字符串
def print_recommendations_from_strings(
        strings,  # list[str]: 输入的字符串列表
        index_of_source_string,  # int: 源字符串在列表中的索引
        k_nearest_neighbors=1,  # int: 推荐的相似字符串数量
):
    """
    输出与源字符串最相似的 k 个字符串。
    Args:
        strings (list): 输入字符串列表。
        index_of_source_string (int): 源字符串在列表中的索引。
        k_nearest_neighbors (int): 要推荐的近邻数量。
    """
    # 生成所有输入字符串的嵌入向量
    embeddings = [embedding_from_string(string) for string in strings]
    # 获取源字符串的嵌入向量
    query_embedding = embeddings[index_of_source_string]

    # 定义余弦相似度函数
    def cosine_similarity(vec1, vec2):
        """
        计算两个向量之间的余弦相似度。
        Args:
            vec1 (list): 向量1
            vec2 (list): 向量2
        Returns:
            float: 余弦相似度值
        """
        return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))

    # 计算源嵌入与所有嵌入之间的距离(1 - 相似度)
    distances = [1 - cosine_similarity(query_embedding, emb) for emb in embeddings]

    # 按照距离升序排列,获取最近邻的索引
    indices_of_nearest_neighbors = np.argsort(distances)

    # 打印源字符串
    query_string = strings[index_of_source_string]
    print(f"源文本: {query_string}")

    # 打印最相似的 k 个字符串及相似度
    k_counter = 0
    for i in indices_of_nearest_neighbors:
        if query_string == strings[i]:  # 跳过与自身的比较
            continue
        if k_counter >= k_nearest_neighbors:  # 限定推荐数量
            break
        k_counter += 1
        print(
            f"""
        --- 推荐 #{k_counter} ---
        相似文本: {strings[i]}
        相似度: {1 - distances[i]:0.3f}"""
        )
    return indices_of_nearest_neighbors

7、获取相似文章

从数据集中提取所有文章的描述,然后分别基于特定主题的文章来获取5篇最相似的文章推荐。

# 获取文章标题列表
article_titles = df["headline_text"].tolist()

# 获取基于某个文本的推荐结果
print("基于文本推荐示例:")
print("财经相关文章推荐")
recommendations = print_recommendations_from_strings(
    strings=article_titles,  # 输入文章标题列表
    index_of_source_string=0,  # 选取第一个文本作为源文本
    k_nearest_neighbors=5,  # 推荐5个最相似的文本
)

API参考

错误码

如果模型调用失败并返回报错信息,请参见错误码进行解决。

调用限制

通用多模态向量API使用过程中存在以下输入类型与格式限制:

输入类型

语言/格式限制

长度/大小限制

文本

中/英文

512Token, 超过512 token长度的文本内容将会被截断

图片

JPG、PNG、BMP

支持以Base64格式或URL形式输入。接受的图片大小上限为 3MB

视频

MP4、MPEG、MPG、WEBM、AVI、FLV、MKV、MOV

接受的视频大小上限为 10MB

关于模型的限流条件,请参见限流