天池大赛Higress插件官方demo详细部署+调试

天池大赛Higress插件官方demo详细部署+调试

契机

使用Higress AI网关优化AI调用成本。就是基于向量召回相似问题的缓存,降低LLM API调用成本。就是开发一个网关插件做QA缓存嘛。前文已经成功复现了hello-world插件,这次结合官方提供的AI-Cache插件自己动手改改,再写点注释放到天池大赛去跑跑分,环境搭建起来确实有很多要注意的地方,所以记录下来。

前期准备

文档中所有变量都是${your_qwen_token}这种形式,需要你自己替换

#docker仓库准备,不多赘述,以后docker login的时候需要这个页面设置的访问凭证
#这个是调试插件CI/CD的关键
https://cr.console.aliyun.com/cn-hangzhou/instance/repositories#申请千问token
[https://help.aliyun.com/zh/dashscope/opening-service](https://help.aliyun.com/zh/dashscope/opening-service)
#保存变量${your_qwen_token}#上传文件到千问,文件下载位置见下图
#地址:https://tianchi.aliyun.com/competition/entrance/532192/informatio
#下载下来,解压缩得到doc.md
curl --location --request POST 'https://dashscope.aliyuncs.com/compatible-mode/v1/files' \--header 'Authorization: ${your_qwen_token}' \--form 'file=@./doc.md' \--form 'purpose=file-extract'
#得到结果如下
{"id":"${your_file_id}","object":"file","bytes":79439,"created_at":1719468299,"filename":"doc.md","purpose":"file-extract","status":"processed"}
#保存变量${your_file_id}

在这里插入图片描述

本地搭建调试

docker运行higress

#本地新建docker-compose.yml如下
#我们只需要网关即可,不需要其他的httpbin容器version: '3.9'
services:higress:#这个镜像包含redis,并且包含了ai-proxy插件image: registry.cn-hangzhou.aliyuncs.com/ztygw/aio-redis:1.4.0-rc.1environment:#开启日志输出- GATEWAY_COMPONENT_LOG_LEVEL=misc:error,wasm:debugports:#管理页面端口- "8080:8080/tcp"#llm端口- "8001:8001/tcp"#redis端口- "6379:6379/tcp"restart: always#直接启动起来
docker compose up

higress管理页面配置

此时容器运行起来了,访问http://localhost:8001,进入higress管理页面,密码随便

创建服务来源

首先创建官方文档中的DNS类型的服务,域名是 dashscope.aliyuncs.com,端口是443

在这里插入图片描述

然后创建一个redis固定地址服务来源,服务地址写127.0.0.1:6379,名称直接写redis

在这里插入图片描述

最后你的服务来源应该如下
在这里插入图片描述

路由配置

创建一条前缀匹配/的路由,转发给上面创建的服务,并附加注解:

higress.io/backend-protocol: HTTPS

higress.io/proxy-ssl-name: dashscope.aliyuncs.com

higress.io/proxy-ssl-server-name: on

就按照下图填写就完了

在这里插入图片描述

配置AI代理插件

这里要把插件打开,并且把 y o u r q w e n t o k e n , {your_qwen_token}, yourqwentoken{your_file_id}填写上去

在这里插入图片描述

LLM访问验证

上面配置好了,此时你的llm就可以使用了

#测试访问
#注意这里是8080端口
curl 'http://localhost:8080/api/openai/v1/chat/completions' \-H 'Accept: application/json, text/event-stream' \-H 'Content-Type: application/json' \--data-raw '{"model":"qwen-long","frequency_penalty":0,"max_tokens":800,"stream":false,"messages":[{"role":"user","content":"higress项目主仓库的github地址是什么"}],"presence_penalty":0,"temperature":0.7,"top_p":0.95}'#如果返回如下格式说明成功
{"id": "from-cache","choices": [{"index": 0,"message": {"role": "assistant","content": "Higress项目的GitHub主仓库地址为: https://github.com/higress-group/higress-group.github.io"},"finish_reason": "stop"}],"model": "gpt-4o","object": "chat.completion","usage": {"prompt_tokens": 0,"completion_tokens": 0,"total_tokens": 0}
}

官方demo添加

加点日志

上面我们已经把项目拷贝下来了,找到官方ai-cache的demo的parseConfig方法,在这里加点日志,等下我们去观察日志插件是否生效

在这里插入图片描述

func parseConfig(json gjson.Result, c *PluginConfig, log wrapper.Log) error {log.Info("开始读取配置...")// 读取redis的基本配置c.RedisInfo.ServiceName = json.Get("redis.serviceName").String()if c.RedisInfo.ServiceName == "" {log.Error("Redis 服务名不能为空")return errors.New("redis service name must not be empty")}log.Infof("Redis 服务名: %s", c.RedisInfo.ServiceName)c.RedisInfo.ServicePort = int(json.Get("redis.servicePort").Int())if c.RedisInfo.ServicePort == 0 {if strings.HasSuffix(c.RedisInfo.ServiceName, ".static") {// use default logic port which is 80 for static servicec.RedisInfo.ServicePort = 80} else {c.RedisInfo.ServicePort = 6379}}log.Infof("Redis 服务端口: %d", c.RedisInfo.ServicePort)c.RedisInfo.Username = json.Get("redis.username").String()log.Infof("Redis 用户名: %s", c.RedisInfo.Username)c.RedisInfo.Password = json.Get("redis.password").String()log.Info("Redis 密码已读取")c.RedisInfo.Timeout = int(json.Get("redis.timeout").Int())if c.RedisInfo.Timeout == 0 {c.RedisInfo.Timeout = 1000}log.Infof("Redis 超时时间: %d ms", c.RedisInfo.Timeout)c.CacheKeyFrom.RequestBody = json.Get("cacheKeyFrom.requestBody").String()if c.CacheKeyFrom.RequestBody == "" {c.CacheKeyFrom.RequestBody = "messages.@reverse.0.content"}log.Infof("Cache Key From RequestBody: %s", c.CacheKeyFrom.RequestBody)c.CacheValueFrom.ResponseBody = json.Get("cacheValueFrom.responseBody").String()if c.CacheValueFrom.ResponseBody == "" {c.CacheValueFrom.ResponseBody = "choices.0.message.content"}log.Infof("Cache Value From ResponseBody: %s", c.CacheValueFrom.ResponseBody)c.CacheStreamValueFrom.ResponseBody = json.Get("cacheStreamValueFrom.responseBody").String()if c.CacheStreamValueFrom.ResponseBody == "" {c.CacheStreamValueFrom.ResponseBody = "choices.0.delta.content"}log.Infof("Cache Stream Value From ResponseBody: %s", c.CacheStreamValueFrom.ResponseBody)c.ReturnResponseTemplate = json.Get("returnResponseTemplate").String()if c.ReturnResponseTemplate == "" {c.ReturnResponseTemplate = `{"id":"from-cache","choices":[{"index":0,"message":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}`}log.Info("Return Response Template 已读取")c.ReturnStreamResponseTemplate = json.Get("returnStreamResponseTemplate").String()if c.ReturnStreamResponseTemplate == "" {c.ReturnStreamResponseTemplate = `data:{"id":"from-cache","choices":[{"index":0,"delta":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}` + "\n\ndata:[DONE]\n\n"}log.Info("Return Stream Response Template 已读取")c.CacheKeyPrefix = json.Get("cacheKeyPrefix").String()if c.CacheKeyPrefix == "" {c.CacheKeyPrefix = DefaultCacheKeyPrefix}log.Infof("Cache Key Prefix: %s", c.CacheKeyPrefix)c.redisClient = wrapper.NewRedisClusterClient(wrapper.FQDNCluster{FQDN: c.RedisInfo.ServiceName,Port: int64(c.RedisInfo.ServicePort),})log.Info("Redis 客户端实例已创建")err := c.redisClient.Init(c.RedisInfo.Username, c.RedisInfo.Password, int64(c.RedisInfo.Timeout))if err != nil {log.Errorf("Redis 客户端初始化失败: %v", err)return err}log.Info("Redis 客户端初始化成功")log.Info("配置初始化成功")return nil
}
还有一个问题onHttpRequestHeaders函数
最后有一个*return types.HeaderStopIteration
最好先改成return types.ActionContinue我不太懂HeaderStopIteration含义,之前卡住的时候我改成ActionContinue就好了*

打包插件+push

#进入ai-cache的目录
cd ~/higress/plugins/wasm-go/extensions/ai-cache#用tinygo打包
tinygo build -o main.wasm -scheduler=none -target=wasi -gc=custom -tags="custommalloc nottinygc_finalizer" ./#需要看看本地有main.wasm生成没有
#作者验证过,macos+arm打包不了#当前目录新建一个DockerFile
vim DockerFile
#写入
FROM scratch
COPY main.wasm plugin.wasm#登陆阿里云docker
docker login --username=${your_docker_username} registry.cn-hangzhou.aliyuncs.com
#输入密码${your_docker_psw}#开始build,注意我这里版本是1.0.0
docker build -t registry.cn-hangzhou.aliyuncs.com/${your_docker_namespace}/${your_docker_repository}:1.0.0 -f Dockerfile .#推送到远程docker
docker push registry.cn-hangzhou.aliyuncs.com/${your_docker_namespace}/${your_docker_repository}:1.0.0#此时得到你的插件地址了
registry.cn-hangzhou.aliyuncs.com/${your_docker_namespace}/${your_docker_repository}:1.0.0

添加ai-cache插件

继续访问higress管理页面http://localhost:8001,新增插件

插件名称:ai-cache

镜像地址:上面你推送过去的地址,这个的ocl://前缀可以不填写,他是自己加上的

执行阶段:认证阶段

优先级:99

~现在插件没有启动,还要其他配置

在这里插入图片描述

访问日志查看

#进入higress容器内部,比如我本地CONTAINER ID = ac11f4f3588a
docker exec -it ${your_container_id} bash#查看日志
#由于我们之前配置了环境变量GATEWAY_COMPONENT_LOG_LEVEL=misc:error,wasm:debug
tail -f /var/log/higress/gateway.log

配置+启动插件

这里要先复制,再开启,配置如下

在这里插入图片描述

cacheKeyFrom:requestBody: "messages.@reverse.0.content"
cacheStreamValueFrom:responseBody: "choices.0.delta.content"
cacheValueFrom:responseBody: "choices.0.message.content"
redis:serviceName: "redis.static"timeout: 2000
returnResponseTemplate: |{"id":"from-cache","choices":[{"index":0,"message":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}
returnStreamResponseTemplate: |-data:{"id":"from-cache","choices":[{"index":0,"delta":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}data:[DONE]

此时看看刚才我们开启的日志,出现以下字样说明没问题了

在这里插入图片描述

验证ai-cache

#测试访问
#注意这里是8080端口
curl 'http://localhost:8080/api/openai/v1/chat/completions' \-H 'Accept: application/json, text/event-stream' \-H 'Content-Type: application/json' \--data-raw '{"model":"qwen-long","frequency_penalty":0,"max_tokens":800,"stream":false,"messages":[{"role":"user","content":"higress项目主仓库的github地址是什么"}],"presence_penalty":0,"temperature":0.7,"top_p":0.95}'#连续两次访问,如果间隔很短,就说明生效了#我们之前把redis映射出来了,可以用redis客户端上去看看key,这里就不多赘述了

迭代升级

后续去higress管理页面,修改ai-cache的镜像地址就行
所以每次代码更新,需要打包代码,打包镜像,推送到docker仓库,修改插件镜像地址

写到最后

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/862709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SecureBoost:一种无损的联邦学习框架

SecureBoost:一种无损的联邦学习框架 文章目录 SecureBoost:一种无损的联邦学习框架1 引言2 预备知识与相关工作3 问题描述4 联邦学习与SecureBoost5 联邦推理6 无损属性的理论分析7 安全讨论8 实验9 结论 摘要——用户隐私保护是机器学习中的一个重要问…

LSS论文与代码详解

本文首发于公众号【DeepDriving】,欢迎关注。 0. 前言 最近几年,BEV感知是自动驾驶领域中一个非常热门研究方向,其核心思想是把多路传感器的数据转换到统一的BEV空间中去提取特征,实现目标检测、地图构建等任务。如何把多路相机的…

关于bim数字孪生threejs中使用glb文件大小优化及加载慢的说明(笔记)

在用three.js开发的时候发现,稍微大一点的glb或者fbx文件加载的时候很慢很卡 一直不理解这个卡和慢取决于哪些条件,下面来详细说一下 1、关于模型 不是越大加载越卡顿,而是却决于三角面数量,当累计三角面数量达到3000万时会出现明…

ASUS/华硕天选5 FX607J系列 原厂Windows11系统

安装后恢复到您开箱的体验界面,带原机所有驱动和软件,包括myasus mcafee office 奥创等。 最适合您电脑的系统,经厂家手调试最佳状态,性能与功耗直接拉满,体验最原汁原味的系统。 原厂系统下载网址:http:…

LLaMA2模型训练加速秘籍:700亿参数效率提升195%!

点击蓝字 关注我们 关注并星标 从此不迷路 计算机视觉研究院 公众号ID | 计算机视觉研究院 学习群 | 扫码在主页获取加入方式 开源地址:https://github.com/hpcaitech/ColossalAI 计算机视觉研究院专栏 Column of Computer Vision Ins…

Microsoft Defender防病毒怎么关闭!详细步骤看这里!

Microsoft Defender是Windows系统中的防病毒软件,提供了实时的安全保护功能。但是,在某些情况下,用户想要关闭系统内的Microsoft Defender功能,但不知道要怎么操作才能关闭?接下来小编给大家带来详细的关闭步骤介绍。 …

柔性数组(flexible array)

柔性数组从C99开始支持使用 1.柔性数组的概念 概念: 结构体中,结构体最后一个元素允许是未知大小的数组,这就叫[柔性数组]的成员 struct S {int n;char arr[]; //数组大小未知(柔性数组成员) }; 柔性数组的特点: 结构体中柔性…

VBA技术资料MF170:调整多个工作薄中签名位置

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

数据可视化如何为智慧农业带来变革

数据可视化如何为智慧农业保驾护航?随着农业现代化的深入推进,智慧农业应运而生,通过集成物联网、大数据、人工智能等先进技术,实现农业生产的数字化、智能化和高效化。而在这一过程中,数据可视化技术作为重要的工具&a…

主从复制、哨兵以及Cluster集群

目录 1.Redis高可用 2.Redis主从复制 2.1 主从复制的作用 2.2 主从复制流程 2.3 搭建Redis主从复制 2.3.1 修改Redis配置文件(Master节点操作) 2.3.2 修改Redis配置文件(Slave节点操作) 2.3.2 验证主从复制结果 3.Redis哨…

基于改进天鹰优化算法(IAO)优化支持向量机(SVM)数据回归预测(IAO-SVM)

改进天鹰优化算法(IAO)见:【智能优化算法】改进的AO算法(IAO)-CSDN博客 支持向量机(SVM)数据时序预测:基于支持向量机的数据回归预测-CSDN博客 代码原理 基于改进天鹰优化算法(IAO)优化支持向量机(SVM)数…

代码随想录算法训练营第三十七天|01背包问题、分割等和子集

01背包问题 题目链接:46. 携带研究材料 文档讲解:代码随想录 状态:忘了 二维dp 问题1:为啥会想到i代表第几个物品,j代表容量变化? 动态规划中,每次决策都依赖于前一个状态的结果,在…

Java中使用键盘录用【Scanner】遇到的问题

目录 一、空格截断问题:二、next()、nextInt()、nextDouble()等nextXxx()与nextLine()连用、混用的问题:问题描述:代码演示问题问题原因:解决办法:示例代码: 最后 Java中使用键盘录入,尤其是通过…

ROS2开发机器人移动

.创建功能包和节点 这里我们设计两个节点 example_interfaces_robot_01,机器人节点,对外提供控制机器人移动服务并发布机器人的状态。 example_interfaces_control_01,控制节点,发送机器人移动请求,订阅机器人状态话题…

力扣SQL50 员工的直属部门 子查询 双重

Problem: 1789. 员工的直属部门 👨‍🏫 参考题解 Code select employee_id, department_id from Employee where primary_flag Y # Y 表明是直属部门 or employee_id in (select employee_idfrom Employeegroup by employee_idhaving count(employee…

【STM32-MAP文件分析】

STM32-MAP文件分析 ■ MDK编译生成文件简介■ .o■ .axf■ .hex■ .crf■ .d■ .dep■ .lnp■ .lst■ .map■ .build_log.htm■ .htm 文件■ .map 文件 ■ map文件分析■ map 文件的 MDK 设置■ 1. 要生成 map 文件 在 Listing 选项卡里面■ 2. Keil5 中打开.map 文件 ■ map 文…

信息学奥赛初赛天天练-38-CSP-J2021阅读程序-约数个数、约数和、埃氏筛法、欧拉筛法筛素数应用

PDF文档公众号回复关键字:20240628 2021 CSP-J 阅读程序3 1阅读程序(判断题1.5分 选择题3分 共计40分 ) 01 #include<stdio.h> 02 using namespace std; 03 04 #define n 100000 05 #define N n1 06 07 int m; 08 int a[N],b[N],c[N],d[N]; 09 int f[N],g[N]; 10 11 …

矩阵快速幂

矩阵快速幂 矩阵&#xff1a; 一个矩阵 A A A&#xff0c;是由 n m n\times m nm 个数字组成&#xff0c; B B B 由 m p m\times p mp 组成&#xff0c;详见下。 A [ a 1 , 1 , a 1 , 2 , a 1 , 3 ⋯ a 1 , m a 2 , 1 , a 2 , 2 , a 2 , 3 ⋯ a 2 , m ⋅ ⋅ ⋅ a n , …

javaSE知识点整理总结(上)

目录 一、面向对象 1. 类、对象、方法 2.面向对象三大特征 &#xff08;1&#xff09;封装 &#xff08;2&#xff09;继承 &#xff08;3&#xff09;多态 二、常用类 1.Object类 2.Array类 3.基本数据类型包装类 4.String类 5.StringBuffer类 6.Math类 7.Random…

摄影楼电子相册打开的正确方式,快来看看

​随着科技的不断发展&#xff0c;电子相册已经成为许多人存储和分享照片的重要方式。然而&#xff0c;你知道如何正确打开电子相册吗&#xff1f;今天&#xff0c;我就来教大家一下电子相册的正确打开方式&#xff0c;快来学习一下吧&#xff01; 第一步&#xff1a;选择合适的…