使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

简单原理:使用 ChatGPT enbedding,对现有的数据文档,将文本转换为向量,进行矢量化处理,并存入Redis向量数据库,实现向量相似度搜索。新的提问过来,先使用 ChatGPT enbedding 处理一次,然后根据Redis向量数据库提供的相似性搜索,找到匹配的答案。

ChatGPT Embeddings是什么?

Embeddings是一种将文本转换为数值向量的技术,它可以让计算机更好地理解和处理自然语言。Embeddings可以将每个单词或者每个句子映射到一个高维空间中的一个点,这个点的坐标就是该单词或句子的向量。

Embeddings可以保留文本中的语义、语法和情感信息,使得具有相似含义或相似用法的单词或句子在空间中距离较近,而具有不同含义或不同用法的单词或句子在空间中距离较远,从而生成更加丰富和准确的向量。

ChatGPT Embeddings指的是通过使用ChatGPT或类似的语言模型生成的数值化表示,这些表示捕捉了文本数据的语义信息。Embeddings是高维空间中的向量,它们将文本转换为一系列数值,这些数值可以用于比较文本之间的相似度、作为机器学习模型的输入特征,或用于其他自然语言处理任务。

在机器学习和自然语言处理中,将词、短语、句子或整个文档转换为向量的过程称为“嵌入”(embedding)。这些嵌入向量通常通过训练大型神经网络模型(如GPT系列、BERT、Word2Vec等)在大量文本数据上获得,以便捕获语言的深层语义和句法特征。

例如,使用ChatGPT模型,您可以输入一个句子或段落,模型将输出一个固定长度的向量,这个向量数值上表示了输入文本的内容。然后,这些嵌入向量可以用于各种应用,比如通过计算两个向量之间的距离来找到语义上相似的文本。

示例请求

curl https://api.openai.com/v1/embeddings 
  -H "Authorization: Bearer $OPENAI_API_KEY" 
  -H "Content-Type: application/json" 
  -d '{
    "input": "The food was delicious and the waiter...",
    "model": "text-embedding-ada-002",
    "encoding_format": "float"
  }'

响应

{
  "object""list",
  "data": [
    {
      "object""embedding",
      "embedding": [
        0.0023064255,
        -0.009327292,
        .... (1536 floats total for ada-002)
        -0.0028842222,
      ],
      "index"0
    }
  ],
  "model""text-embedding-ada-002",
  "usage": {
    "prompt_tokens"8,
    "total_tokens"8
  }
}
  • 文档地址 https://platform.openai.com/docs/api-reference/embeddings/create
  • 官网示例 https://github.com/openai/openai-cookbook/

Redis向量数据库是什么?

Redis 向量数据库是一种专门为向量数据存储和检索而设计的数据库。它基于 Redis 的内存数据库,具有高性能和可扩展性,非常适合存储和查询高维向量数据。

向量数据是一种由多个数值组成的多维数据结构,广泛应用于机器学习、自然语言处理、图像处理等领域。传统的关系型数据库不擅长存储和处理向量数据,而 Redis 向量数据库则专为处理向量数据而设计,具有以下特点:

  • 高性能: Redis 向量数据库采用内存数据库作为存储引擎,具有极高的读写性能,可以满足实时查询和分析的需求。
  • 可扩展性: Redis 向量数据库支持水平扩展,可以轻松地通过添加更多的节点来提高数据库的吞吐量和容量。
  • 易于使用: Redis 向量数据库提供了友好的 API,可以轻松地将向量数据存储、查询和检索。

Redis 向量数据库的一些典型应用场景包括:

  • 文本相似度分析: 将文本编码成向量,然后使用向量相似度来衡量文本之间的相似性。
  • 图像相似度搜索: 将图像编码成向量,然后使用向量相似度来搜索与查询图像相似的图像。
  • 推荐系统 将用户和物品编码成向量,然后使用向量相似度来推荐用户可能感兴趣的物品。
  • 欺诈检测: 将正常的交易和欺诈交易编码成向量,然后使用向量相似度来检测欺诈交易。

如果您需要存储和处理向量数据,那么 Redis 向量数据库是一个非常好的选择。它具有高性能、可扩展性和易于使用的特点,可以帮助您快速构建功能强大的向量数据应用程序。

PHP 代码实现

按照之前编写需要RedisSearchRedisJSON 两个扩展模块支持,使 Redis 得以支持结构化数据的搜索。[Redis Stack技术栈入门实战指南] https://mp.weixin.qq.com/s/jfVdaakjiNRQKSNf79zgtA

安装openai依赖包

注意:该依赖包需要PHP版本PHP >=8.1。可以通过php -v查看是否符合版本要求

/var/www/webman-admin # php -v
PHP 8.2.10 (cli) (built: Sep  2 2023 07:09:39) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.10, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.10, Copyright (c), by Zend Technologies

composer 安装扩展包

composer require openai-php/client

安装过程

使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

Chat 测试

$apiKey = 'xxxxxxxxxxxxxxxxxx';
$client = OpenAI::factory()
    ->withApiKey($apiKey)
    ->withBaseUri('api.openai.com/v1')
    ->withHttpClient($client = new GuzzleHttpClient([]))
    ->withStreamHandler(fn(PsrHttpMessageRequestInterface $request): PsrHttpMessageResponseInterface => $client->send($request, [
        'stream' => true // Allows to provide a custom stream handler for the http client.
    ]))->make();
$result = $client->chat()->create([
    'model' => 'gpt-3.5-turbo-0613',
    'messages' => [
        ['role' => 'user''content' => 'Tinywan 程序员是谁?'],
    ],
]);
echo '[开源技术小栈响应]:'.$result->choices[0]->message->content;
return response_json(0,'success');

请求访问地址:http://127.0.0.1:8201/test/openai。以上会话打印以下内容表示SDK没问题

使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

更多了解:https://platform.openai.com/docs/api-reference/chat/create

Embeddings 使用

$apiKey = 'xxxxxxxxxxxxxxxxxx';
$client = OpenAI::factory()
    ->withApiKey($apiKey)
    ->withBaseUri('api.openai.com/v1')
    ->withHttpClient($client = new GuzzleHttpClient([]))
    ->withStreamHandler(fn(PsrHttpMessageRequestInterface $request): PsrHttpMessageResponseInterface => $client->send($request, [
        'stream' => true // Allows to provide a custom stream handler for the http client.
    ]))->make();


/** TODO 1、利用ChatGTP Embeddings功能,将文本转换为向量 */
$input = 'Hi,我是Tinywan,开源技术小栈公众号作者。一只程序猿,毕业于二流院校,目前在杭州工作。';
$response = $client->embeddings()->create([
    'model' => 'text-embedding-ada-002',
    'input' => $input,
    'encodding_format' => 'float' // 向量是一组多维的数组,数组元素为 float 类型数据。
]);

/** TODO 2、将文本向量并存储到Redis中,实现向量相似度搜索 */
$textEmbeddingVector = $response['data'][0]['embedding'];
$indexName = 'tinywan:embedding:2024';
try {
  $indexExist = Redis::rawCommand('FT.INFO'$indexName);
} catch (Throwable $e) {
  $indexExist = false;
}

/** TODO 3、索引不存在,创建索引 */
if(!$indexExist) {
  Redis::rawCommand('FT.CREATE'$indexName'on''JSON''PREFIX''1'"$indexName:"'SCHEMA',
      '$.text_embedding''AS''text_embedding''VECTOR''FLAT''6''DIM''1536''DISTANCE_METRIC''COSINE''TYPE''FLOAT32');
}
/** TODO 4、添加向量存储 */
$embeddingKey = 'tinywan:embedding:2024:'.time();
$embeddingValue = [
  'key' => $embeddingKey,
  'content' => $input,
  'text_embedding' => $textEmbeddingVector
];
Redis::rawCommand('JSON.SET'$embeddingKey'$', json_encode($embeddingValue, JSON_UNESCAPED_UNICODE));

请求访问地址:http://127.0.0.1:8201/test/openai。会打印出好多向量

使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

这里内容比较多

[
  0.01726415,
  -0.024315901,
  -0.010605723,
  -0.02709727,
  -0.018514361,
  0.017460812,
  -0.022475703,
  0.0029130618,
  -0.0068199714,
  -0.008941116,
  ....
  ....
]

最终数据存储结果

使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

搜索

try {
  $apiKey = 'xxxxxxxxxxxxxxxxxx';
  $client = OpenAI::factory()
      ->withApiKey($apiKey)
      ->withBaseUri('api.openai.com/v1')
      ->withHttpClient($client = new GuzzleHttpClient([]))
      ->withStreamHandler(fn(PsrHttpMessageRequestInterface $request): PsrHttpMessageResponseInterface => $client->send($request, [
          'stream' => true // Allows to provide a custom stream handler for the http client.
      ]))->make();

    /** TODO 1、利用ChatGTP Embeddings功能,将文本转换为向量 */
    $response = $client->embeddings()->create([
        'model' => 'text-embedding-ada-002',
        'input' => '开源技术小栈',
        'encodding_format' => 'float' // 向量是一组多维的数组,数组元素为 float 类型数据。
    ]);
    $embedding = $response['data'][0]['embedding'];
    $blob = '';
    foreach ($embedding as $value) {
        $blob .= pack('f'$value);
    }
    $indexName = 'tinywan:embedding:2024';
    $count = 10;
    $redisResult = Redis::rawCommand('FT.SEARCH'$indexName'*=>[KNN ' .
        $count . ' @text_embedding $blob]''PARAMS''2''blob'$blob'SORTBY''__text_embedding_score''DIALECT''2');
    /** TODO 2、查询向量分数最高的1条数据 */
    if (!isset($redisResult[2][3])) {
        return json(['content' => []]);
    }
    /** TODO 3、返回精准查询内容 */
    $resultArr = json_decode($redisResult[2][3], true);
} catch (Throwable $throwable) {
    var_dump('异常错误 ' . $throwable->getMessage() . '|' . $throwable->getFile() . '|' . $throwable->getLine());
    return json([]);
}
return json(['content' => $resultArr['content']]);

搜索方式: 使用 KNN 搜索方式,根据给定的一段文本,搜索相似的文档

查询案例和法语

127.0.0.1:6379> FT.SEARCH books-idx "*=>[KNN 10 @title_embedding $query_vec AS title_score]" PARAMS 2 query_vec <"Planet Earth" embedding BLOB> SORTBY title_score DIALECT 2

查询结果

使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎
使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

搜索程序猿程序猿就被精准的排在第一位啦!

使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

本文使用 ChatGPT Embeddings 的向量化处理,Redis JSON 和搜索功能,演示了如何实现一个简单的文本相似性搜索。


原文始发于微信公众号(开源技术小栈):使用PHP和Redis向量数据库基于ChatGPT实现文本搜索引擎

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/247905.html

(0)
李, 若俞的头像李, 若俞

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!