PAI-Rec 是一套推荐在线服务的引擎,把推荐服务的各个流程串联起来,并且提供了基本的预定义实现。**用户只需要提供配置就可以使用内置的实现逻辑**。用户也可以提供自定义的实现,然后通过 register 机制注册到引擎里。接下来我们简单的跑一下流程。 ## 第一步:创建项目 1. 首先我们需要下载一个可执行文件 ​ linux下载: [paireccmd](http://pai-rec-public.oss-cn-shanghai.aliyuncs.com/command/bin/pairecmd) ​ mac下载: [pairecmdmac](http://pai-rec-public.oss-cn-shanghai.aliyuncs.com/command/bin/pairecmdmac) 2. 将下载下来的文件更改一下执行权限,`chmod +x pairecmdmac` 3. 我们把项目名称取为 `pairec-demo`,执行 `pairecmdmac`,(我自己的是Mac,所以选择的是`pairecmdmac`) ``` ./pairecmdmac project --name pairec-demo ``` 执行结果如下: ![7E2F98E2-FDD4-40A6-B826-D9956B01DD62](./PaiRec-Demo-Pictures/7E2F98E2-FDD4-40A6-B826-D9956B01DD62.png) 我们可以找到我们创建的项目文件夹-`pairec-demo`,目录结构如下所示: ![C4CD3693-7708-4E1A-BA8A-C9CD830BF4A8](./PaiRec-Demo-Pictures/C4CD3693-7708-4E1A-BA8A-C9CD830BF4A8.png) 其中 `conf/config.json.production` 就是我们提供自己配置的文件,也是后面我们主要进行操作的文件 在 `go.mod` 中已经引入了 `pairec`包,所以我们只需要执行一下 `make` 即可,依赖包便引入进来了,项目的整体框架已经创建好了,接下来就可以修改配置文件了。 *目前 pairec 还没有对外开放, 使用时,以源代码形式给到客户,在 go.mod 加入 replace gitlab.alibaba-inc.com/pai_biz_arch/pairec => pairec 路径, 可以引用到。* ## 第二步:修改配置文件 整个推荐的大致流程是:召回--->过滤--->特征加载--->打分---->排序,所以我们先配置召回策略 ### 召回配置 我们可以先配置 `HologresConfs:{}`,它代表的是一个holo实例。我们在此次demo中所选择的存储库都是`hologres` + 登陆阿里云,搜索`hologres`,选择实例列表,并选择相应的区域 + ![image-20210706133011842](./PaiRec-Demo-Pictures/image-20210706133011842.png) + 查看该**实例的连接方式**,并配置在项目中,例: ```shell "HologresConfs": { "pairec-holo":{// 实例的自定义 name "DSN": "postgres://:@:/?sslmode=disable&connect_timeout=1" // 实例的连接地址,在实例详情中有详细说明 } }, ``` holo实例配置好了之后,接下来要配置召回的表,我们在这里用一种召回方式举例:`U2IRecall` ```shell "RecallConfs": [ { "Name":"U2IRecall", //自定义的召回名称 "RecallType": "UserCustomRecall",//所对应的召回 Func "RecallCount" :1000,//召回数量 "DaoConf":{ "AdapterType": "hologres", "HologresName": "pairec-holo",//上面自定义的holo实例名称 "HologresTableName": "recall_u2i"//召回的表名 } } ] ``` 我们这里提供了一个已脱敏的 [召回表](https://pairec-holo-test.oss-cn-beijing.aliyuncs.com/data/recall_test_data.csv),可以导入自己的holo库进行使用,对表简单的做一个说明: | user_id | Item_ids | | -------- | ------------------------------------------------------------ | | 0001 | 1823::0.0047,3252::0.0047, | | 用户的id | 多个item,每个item以逗号分隔,每个item又以冒号分为三个字段,分别是item_id,recallType,score | 接下来还需要配置一下场景 `SceneConfs` ```shell "SceneConfs": { "video_feed":{//场景名 "default":{//catagory,没有明确定义,会走default "RecallNames":["U2IRecall"]//此场景所需的召回策略 } } }, ``` ### 过滤配置 `FilterConfs `支持曝光过滤`(User2ItemExposureFilter)`, 数量调整`(AdjustCountFilter)`, U2I 自定义过滤`(User2ItemCustomFilter)`,我们在此选择一个简单的数量调整过滤 ```shell "FilterConfs": [ { "Name": "AdjustCountFilter", //自定义的过滤名称 "FilterType": "AdjustCountFilter", //与之相对应的Func名称 "RetainNum": 400 //保留的数量 } ], ``` 配置好 `FilterConfs`之后,我们可以再配置 `FilterName`,这里的作用是 根据不同的场景选择不同的 过滤方式 ```shell "FilterNames": { "video_feed": [//场景名称,如果没有配置,则会走default场景 "UniqueFilter", // 每个场景默认加上,为了对多路召回进行去重 "AdjustCountFilter"//上面自定义的过滤名称 ], "default": [ ] }, ``` ### 特征加载配置 特征配置我们在这里只做一个简单的加载**用户特征**,特征加载的配置实例及说明如下 ```shell "FeatureConfs": { "video_feed": {//场景名 "AsynLoadFeature": true,//是否异步加载特征 "FeatureLoadConfs": [ { "FeatureDaoConf": { "AdapterType": "hologres", "HologresName": "pairec-holo",//holo实例的名字 "UserFeatureKeyName": "userid", //用户特征表中的存储用户id的字段 "FeatureKey": "user:uid", //服务中存在于user feature中的值 "HologresTableName": "all_feature", //存储用户特征的表名 "UserSelectFields": "*", //所要选择的特征字段,可根据字段名自行选择 "FeatureStore": "user" //查询出来的特征存储的位置:user或者item }, "Features": [] //可以在这里新增一些特征,此次我们只用表里的特征 } } } ``` 特征加载的本质就是将表中某个用户的特征加载到user的feature里面,所以上面的配置可以归结为一句`sql:SELECT ${UserSelectFields} FROM ${HologresTableName} WHERE ${UserFeatureKeyName} = ${FeatureKey} ` 我们这里提供了一个已脱敏的用户 [特征表](https://pairec-holo-test.oss-cn-beijing.aliyuncs.com/data/feature_test_data.csv),可以下载下来导入自己的holo库进行使用 对表做一个简单的说明: | userid | is_new_userid | level | is_member | gender | ...... | | ------ | ------------- | ----: | --------- | ------ | ------ | | 000001 | 0 | 1 | 0 | M | ...... | | 000002 | 1 | 2 | 1 | F | ...... | *此表的表名对应`FeatureConfs`配置中的`HologresTableName`,字段`userid`对应`UserFeatureKeyName`* ### 算法配置 我们首先需要配置 `AlgoConfs`,此处配置的模型的一些信息 ```shell "AlgoConfs": [ { "Name": "demo_algo", //自定义的模型名称 "Type": "EAS", //因为我们的模型是部署在EAS上,所以这里我们填EAS "EasConf": { "Processor": "EasyRec", //模型的Processor,这里我们选EasyRec,还支持其他多种类型,如PMML,ALINK_FM,TensorFlow等 "Timeout": 500, //连接模型的超时时间 "ResponseFuncName": "easyrecMutValResponseFunc", //eas processor对应的FuncName "Url": "http://1103287870424018.vpc.cn-beijing.pai-eas.aliyuncs.com/api/predict/sv_dbmtl",//模型的地址 "Auth": "xxxxxx" //模型的请求授权 } } ], ``` 模型的信息配置好之后,需要再配置 `RankConfs` ```shell "RankConf": { "video_feed": {//场景名 "RankAlgoList": [ "demo_algo" //上面algo配置中的自定义模型名称 ], "RankScore": "${demo_algo}" //模型返回分数的计算公式 }, ``` ## 第三步:定义controller 配置完成之后,我们就可以注册路由,在创建项目时,已经自动创建了一个controller模版,并且已经在`main.go`中注册,可以根据此模版酌情修改,下面做一些简单说明: ```yaml RecommendParam: 客户端请求的参数格式 RecommendResponse: 服务端返回的数据格式 ItemData: 是RecommendResponse中Items的单独的条目 ``` ## 第四步: 本地测试 由于我们的项目中已经提供了`makefile`文件, 1. 编译 `make build` 2. 启动并滚动日志输出命令 `PAIREC_ENVIRONMENT=prepub ./pairec-demo --config=conf/config.json.production -alsologtostderr` 控制台出现 `server start` 即为正常 请求格式: ```json curl 'http://localhost:8000/api/rec/feed' -d '{"uid":"1000000238","scene_id":"video_feed","size":5}' ``` 返回如下结果即为模型正常 ```json { "code":200, "msg":"success", "request_id":"e332fe9c-7d99-45a8-a047-bc7ec33d07f6", "experiment_id": "", "items":[ { "item_id":"3v5RE7417j7R", "retrieve_id":"u2i_recall", "score": 0.5 }, ... ] } ``` ## 第五步:部署 目前部署有两种方式:部署在EAS 或者 K8S 上,此次我们选择部署在EAS,对EAS不了解的同学可以点击[这里](https://help.aliyun.com/document_detail/113696.html?spm=a2c4g.11174283.6.777.4d8e4c07Y8EmM1),简单看一下EAS的文档。 ### 创建仓库 首先我们需要创建一个docker远程仓库,登陆阿里云搜索**容器镜像服务** ![image-20210716111755841](./PaiRec-Demo-Pictures/image-20210716111755841.png) *可以根据自己的需求来选择创建**企业版实例**或者**个人版实例*** *接下来创建好镜像仓库,点击进去可以查看此仓库的一些操作指南,如 login,pull,push的一些命令* *然后在终端运行 `make release` 命令,将代码打包成镜像,上传至创建好的远程仓库* ### 下载客户端工具 linux下载:[32位](http://easdata.oss-cn-hangzhou-zmf.aliyuncs.com/tools/eascmd32),[64位](http://easdata.oss-cn-hangzhou-zmf.aliyuncs.com/tools/eascmd64) mac下载:[点击下载]( http://easdata.oss-cn-hangzhou-zmf.aliyuncs.com/tools/eascmdmac64) *下载完成之后不需要安装,直接调用即可,调用之前请执行 `chmod +x eascmd64` 为文件增加可执行权限* ### 对用户进行认证 ```sh ./eascmdmac64 config -i -k [-e Endpoint] ``` *注:点击右上角的个人信息可以获得 **AccessKeyID** 和 **AccessKeySecret*** ***Endpoint**是服务地域,地域和Endpoint对应的取值请参见[表](https://help.aliyun.com/document_detail/195500.html?spm=a2c4g.11186623.6.789.12914e9aTz4foD#table-m59-rz7-ha4)* 执行结果如下: ![image-20210716140140159](./PaiRec-Demo-Pictures/image-20210716140140159.png) ### 配置`service.json`文件 这里提供一个简单的模板,详细参数说明可以参考[命令使用说明](https://help.aliyun.com/document_detail/111031.html?spm=a2c4g.11186623.6.790.6ffe4e9avaFuwE) ```shell { "containers": [ { "image": "registry-vpc.us-west-1.aliyuncs.com/.....", //镜像 "env":[], "port": 8000, //服务对外端口 "command": "/usr/bin/rec_entrypoint.sh" } ], "dockerAuth": "XXXXX", //docker的Auth信息 "metadata": { "instance": 1, //服务启动的instance数目 "cpu": 1, //每个instance需要的cpu数目 "memory": 4000 //每个instance需要的内存大小,单位为M }, "name": "pairec_demo" //服务名称 } ``` 其中`dockerAuth` 指定docker registry的认证信息,目前支持username:password | base64的方式,如 ```sh $echo -n "abcd:abcde12345" | base64 YWJjZDphYmNkZTEyMzQ1 ``` ### 服务部署 ```sh eascmd create service.json ``` 执行结果如下: ​ 至此,服务已经成功部署在EAS上了 ### 服务调用 + 打开阿里云搜索**机器学习平台PAI** ![image-20210716143428684](./PaiRec-Demo-Pictures/image-20210716143428684.png) + 点击左栏的模型在线服务,然后选择自己部署的区域,就可以看到我们部署的服务了 ![](./PaiRec-Demo-Pictures/image-20210716143627603.png) + 选择我们部署的 `pairec_demo` 点击进入 ![image-20210716144238406](./PaiRec-Demo-Pictures/image-20210716144238406.png) + 点击调用方式,就可以根据相应的调用方式对我们部署的服务进行请求了,例如 ```json curl 'http://xxxxxxxx/api/rec/feed' -H 'Authorization:XXXXXXX' -d '{"uid":"1000000238","scene_id":"video_feed","size":5}' ``` ### 服务运维 后期如果想对以部署的服务进行参数更改,如镜像版本,内存大小等,可以先更改 `service.jaon` 文件,然后执行 下面命令即可,更多更详细的命令可以参见 [命令说明](https://help.aliyun.com/document_detail/111031.html?spm=a2c4g.11174283.6.790.4d8e4c07nofYlA) ```sh ./eascmd modify pairec_demo -s service.json ```