本文通过示例为您介绍如何使用Easyrec算法库进行模型训练、部署在线服务,并形成例行化Pipeline工作流。

前提条件

  • 已创建DataScience集群,并且选择了Kubeflow服务,详情请参见创建集群
  • 本地安装了PuTTY和文件传输工具(SSH Secure File Transfer Client)。
  • 下载dsdemo代码:请已创建DataScience集群的用户,使用钉钉搜索钉钉群号32497587加入钉钉群以获取dsdemo代码。

操作流程

  1. 步骤一:准备工作
  2. 步骤二:提交任务
  3. (可选)步骤三:制作Hive CLI、Spark CLI、dscontroller、Hue、notebook或httpd镜像
  4. 步骤四:编译Pipeline
  5. 步骤五:上传Pipeline文件
  6. 步骤六:创建并运行Experiments
  7. (可选)步骤七:查看Pipeline状态
  8. 步骤八:模型预测
  9. 步骤九:通过PairecEngine部署在线服务

步骤一:准备工作

  1. 可选:安装软件包。
    1. 通过SSH方式连接集群,详情请参见登录集群
    2. 在Header节点执行以下命令,安装seldon_core kfp。
      pip3.7 install seldon_core kfp configobj
      说明 如果已经安装seldon_core kfp,可以跳过该步骤。
  2. 登录容器镜像服务控制台,开通个人免费版ACR,并创建命名空间。
    ACR创建命名空间详情,请参见命名空间的基本操作
    说明 如果您选用的是ACR企业版,则可以设置对VPC开放,以提升安全性。
  3. 修改config文件的REGISTRY地址和experiment命名空间名称,并登录ACR。
    1. 执行以下命令,进入ml_on_ds目录。
      sudo cd /root/dsdemo/ml_on_ds
    2. 修改config文件中的REGISTRY地址。
      # !!! Extremely Important !!!
      # !!! You must use A NEW EXP different from others !!!
      EXP=exp1
      
      #!!! ACR, Make sure NAMESPACE is public !!!
      REGISTRY=registry-vpc.cn-beijing.aliyuncs.com
      NAMESPACE=dsexperiment
      
      #k8s namespace, must be same with username when you are using sub-account.
      KUBERNETES_NAMESPACE=default
      
      #kubernetes dashboard host, header1's public ip or inner ip.
      KUBERNETES_DASHBOARD_HOST=39.104.**.**:32699
      
      #PREFIX, could be a magic code.
      PREFIX=prefix
      
      #sc
      NFSPATH=/mnt/disk1/k8s_pv/default_storage_class/
      #NFSPATH=/mnt/disk1/nfs/ifs/kubernetes/
      
      # region
      REGIONID=cn-default
      
      # emr-datascience clusterid
      CLUSTERID="C-DEFAULT"
      
      #HDFSADDR, train/test dir should be exist under $HDFSADDR, like
      #user
      #└── easy_rec
      #    ├── 20210917
      #    │   ├── test
      #    │   │   ├── test0.csv
      #    │   │   └── _SUCCESS
      #    │   └── train
      #    │       ├── train0.csv
      #    │       └── _SUCCESS
      #    └── 20210918
      #        ├── test
      #        │   ├── test0.csv
      #        │   └── _SUCCESS
      #        └── train
      #            ├── train0.csv
      #            └── _SUCCESS
      HDFSADDR=hdfs://192.168.**.**:9000/user/easy_rec/metric_learning_i2i
      MODELDIR=hdfs://192.168.**.**:9000/user/easy_rec/metric_learning_i2i
      
      REGEX="*.csv"
      SUCCESSFILE="train/_SUCCESS,test/_SUCCESS,hdfs://192.168.**.**:9000/flag"
      
      EVALRESULTFILE=experiment/eval_result.txt
      
      # for allinone.sh development based on supposed DATE & WHEN & PREDATE
      DATE=20220405
      WHEN=20220405190001
      PREDATE=20220404
      
      # for daytoday.sh & multidays training, use HDFSADDR, MODELDIR
      START_DATE=20220627
      END_DATE=20220628
      
      #HIVEINPUT
      DATABASE=testdb
      TRAIN_TABLE_NAME=tb_train
      EVAL_TABLE_NAME=tb_eval
      PREDICT_TABLE_NAME=tb_predict
      PREDICT_OUTPUT_TABLE_NAME=tb_predict_out
      PARTITION_NAME=ds
      
      #DSSM: inference user/item model with user&item feature
      #metric_learning_i2i: infernece model with item feature
      #SEP: user&item feature file use same seperator
      USERFEATURE=taobao_user_feature_data.csv
      ITEMFEATURE=taobao_item_feature_data.csv
      SEP=","
      
      # faiss_mysql: mysql as user_embedding storage, faiss as itemembedding index.
      # holo_holo: holo as user & item embedding , along with indexing.
      VEC_ENGINE=faiss_mysql
      MYSQL_HOST=mysql.bitnami
      MYSQL_PORT=3306
      MYSQL_USER=root
      MYSQL_PASSWORD=emr-datascience
      
      #wait before pod finished after easyrec's python process end.
      #example: 30s 10m 1h
      WAITBEFOREFINISHED=10s
      
      #tf train
      #PS_NUMBER take effect only on training.
      #WORKER_NUMBER take effect on training and predict.
      TRAINING_REPOSITORY=tf-easyrec-training
      TRAINING_VERSION=latest
      PS_NUMBER=2
      WORKER_NUMBER=3
      SELECTED_COLS=""
      EDIT_CONFIG_JSON=""
      #tf export
      ASSET_FILES=""
      
      CHECKPOINT_DIR=
      
      #pytorch train
      PYTORCH_TRAINING_REPOSITORY=pytorch-training
      PYTORCH_TRAINING_VERSION=latest
      PYTORCH_MASTER_NUMBER=1
      PYTORCH_WORKER_NUMBER=3
      
      #jax train
      JAX_TRAINING_REPOSITORY=jax-training
      JAX_TRAINING_VERSION=latest
      JAX_MASTER_NUMBER=2
      JAX_WORKER_NUMBER=3
      
      #easyrec customize action
      CUSTOMIZE_ACTION=easy_rec.python.tools.modify_config_test
      USERDEFINEPARAMETERS="--template_config_path hdfs://192.168.**.**:9000/user/easy_rec/rec_sln_test_dbmtl_v3281_template.config --output_config_path hdfs://192.168.**.**:9000/user/easy_rec/output.config"
      
      #hivecli
      HIVE_REPOSITORY=ds_hivecli
      HIVE_VERSION=latest
      
      #ds-controller
      DSCONTROLLER_REPOSITORY=ds_controller
      DSCONTROLLER_VERSION=latest
      
      #notebook
      NOTEBOOK_REPOSITORY=ds_notebook
      NOTEBOOK_VERSION=latest
      
      #hue
      HUE_REPOSITORY=ds_hue
      HUE_VERSION=latest
      
      #httpd
      HTTPD_REPOSITORY=ds_httpd
      HTTPD_VERSION=latest
      
      #postgist
      POSTGIS_REPOSITORY=ds_postgis
      POSTGIS_VERSION=latest
      
      #customize
      CUSTOMIZE_REPOSITORY=ds_customize
      CUSTOMIZE_VERSION=latest
      
      #faissserver
      FAISSSERVER_REPOSITORY=ds_faissserver
      FAISSSERVER_VERSION=latest
      
      #vscode
      VSCODE_REPOSITORY=ds_vscode
      VSCODE_VERSION=latest
      
      # ak/sk for cluster resize, only support resize TASK now!!!
      EMR_AKID=AAAAAAAA
      EMR_AKSECRET=BBBBBBBB
      HOSTGROUPTYPE=TASK
      INSTANCETYPE=ecs.g6.8xlarge
      NODECOUNT=1
      SYSDISKCAPACITY=120
      SYSDISKTYPE=CLOUD_SSD
      DISKCAPACITY=480
      DISKTYPE=CLOUD_SSD
      DISKCOUNT=4
      
      # pvc_name, may not be changed, cause EXP will make sure that two or more experiment will not conflicts.
      PVC_NAME="easyrec-volume"
      
      SAVEDMODELS_RESERVE_DAYS=3
      
      HIVEDB="jdbc:hive2://192.168.**.**:10000/zqkd"
      
      #eval threshold
      THRESHOLD=0.3
      
      #eval result key, 'auc' 'auc_ctcvr' 'recall@5'
      EVALRESULTKEY="recall@1"
      
      #eval hit rate for vector recall
      ITEM_EMB_TABLE_NAME=item_emb_table
      GT_TABLE_NAME=gt_table
      EMBEDDING_DIM=32
      RECALL_TYPE="u2i"
      TOPK=100
      NUM_INTERESTS=1
      KNN_METRIC=0
      
      # sms or dingding
      ALERT_TYPE=sms
      
      # sms alert
      SMS_AKID=AAAAAAAA
      SMS_AKSECRET=BBBBBBBB
      SMS_TEMPLATEDCODE=SMS_220default
      SMS_PHONENUMBERS="186212XXXXX,186211YYYYY"
      SMS_SIGNATURE="mysignature"
      
      # dingtalk alert
      ACCESS_TOKEN=AAAAAAAA
      
      EAS_AKID=AAAAAAAA
      EAS_AKSECRET=BBBBBBBB
      EAS_ENDPOINT=pai-eas.cn-beijing.aliyuncs.com
      EAS_SERVICENAME=datascience_eastest
      
      # ak/sk for access oss
      OSS_AKID=AAAAAAAA
      OSS_AKSECRET=BBBBBBBB
      OSS_ENDPOINT=oss-cn-huhehaote-internal.aliyuncs.com
      OSS_BUCKETNAME=emrtest-huhehaote
      # !!! Do not change !!!
      OSS_OBJECTNAME=%%EXP%%_faissserver/item_embedding.faiss.svm
      
      # ak/sk for access holo
      HOLO_AKID=AAAAAAAA
      HOLO_AKSECRET=BBBBBBBB
      HOLO_ENDPOINT=hgprecn-cn-default-cn-beijing-vpc.hologres.aliyuncs.com
      
      #tensorboard
      TENSORBOARDPORT=6006
      
      #nni port
      NNIPORT=38080
      
      #jupyter password
      JUPYTER_PASSWORD=emr-datascience
      
      #enable_overwrite
      ENABLE_OVERWRITE=true
      
      #For some users who are running pyspark & meachine learning jobs in jupyter notebook.
      #ports for mapping when notebook enabled, multi-users will conflict on same node.
      HOSTNETWORK=true
      MAPPING_JUPYTER_NOTEBOOK_PORT=16200
      MAPPING_NNI_PORT=16201
      MAPPING_TENSORBOARD_PORT=16202
      MAPPING_VSCODE_PORT=16203
    3. 执行以下命令,登录您的ACR,以便后续push镜像。
      docker login --username=<用户名> <your_REGISTRY>-registry.cn-beijing.cr.aliyuncs.com
      说明 ACR需要开启匿名访问并开通公开访问权限,方便pull镜像。代码中的<用户名>为您在容器镜像服务ACR控制台上配置的访问凭证,配置详情请参见配置访问凭证<your_REGISTRY>为您前一步中查看到的REGISTRY地址。
  4. 挂载NAT网关访问ACR,详情请参见创建和管理公网NAT网关实例
  5. 准备测试数据。
    重要 您可以将测试数据写到DataScience集群的HDFS中,也可以按需写到您自己的HDFS中,但需要保证网络畅通。
    # 选ppd, prepare test data.
    sh allinlone.sh

    根据返回信息提示,选择ppd) Prepare data

步骤二:提交任务

重要 需要修改config的REPOSITORY地址为您自己的ACR仓库地址、VERSION版本号以及experiment命名空间名称。
  1. 执行allinone.sh文件。
    sh allinone.sh -d
    返回信息如下。
    loading ./config
    
    You are now working on k8snamespace: default
    
    *** Welcome to DataScience ***
    0)        Exit                                                                 k8s: default
    ppd)      Prepare data           ppk)      Prepare DS/K8S config   cacr)     checking ACR
    1|build)  build training image   bnt)      build notebook image    buildall) build all images(slow)
    dck)      deletecheckpoint       ser)      showevalresult
    apc)      applyprecheck          dpc)      deleteprecheck
    2)        applytraining          3)        deletetraining
    4)        applyeval              5)        deleteeval
    4d)       applyevaldist          5d)       deleteevaldist
    4hr)      applyevalhitrate       5hr)      deleteevalhitrate
    6)        applyexport            7)        deleteexport
    8)        applyserving           9)        deleteserving
    10)       applypredict           11)       deletepredict
    12)       applyfeatureselection  13)       deletefeatureselection
    14)       applycustomizeaction   15)       deletecustomizeaction
    16)       applypytorchtraining   17)       deletepytorchtraining
    mt)       multidaystraining      dmt)      deletemultidaystraining
    me)       multidayseval          dme)      deletemultidayseval
    cnt)      createnotebook         dnt)      deletenotebook          snt)      shownotebooklink
    cft)      createsftp             dft)      deletesftp              sft)      showsftplink
    che)      createhue              dhe)      deletehue               she)      showhuelink
    chd)      createhttpd            dhd)      deletehttpd             shd)      showhttpdlink
    cvs)      createvscode           dvs)      deletevscode            svs)      showvscodelink
    a)        kubectl get tfjobs     b)        kubectl get sdep        c)        kubectl get pytorchjobs
    mp|mpl)   compile mlpipeline     bp|bpl)   compile bdpipeline      bu)       bdupload
    tb)       tensorboard            vc)       verifyconfigfile        spl)      showpaireclink
    tp)       kubectl top pods       tn)       kubectl top nodes       util)     show nodes utils
    logs)     show pod logs          setnl)    set k8s node label
    e|clean)  make clean             cleanall) make cleanall           sml)      showmilvuslink
    sall)     show KubeFlow/Grafana/K8SOverview/Spark/HDFS/Yarn/EMR link
    99)       kubectl get pods       99l)      kubectl get pods along with log url
    >
  2. 输入选项并单击回车。
    您可以通过Tensorboard查看训练过程中的auc曲线:
    1. 执行以下命令,进入ml_on_ds目录。
      sudo cd /root/dsdemo/ml_on_ds
    2. 执行以下命令,运行Tensorboard。
      sh run_tensorboard.sh

      选择tb, 会显示当前实验的ckpt的Tensorboard信息,或者执行sh run_tensorboard.sh 20211209命令,查看20211209训练ckpt的Tensorboard信息。

      说明
      • 默认使用config里TODAY_MODELDIR的modeldir。您也可以指定日期的modeldir,例如sh run_tensorboard.sh hdfs://192.168.**.**:9000/user/easy_rec/20210923/
      • 您可以自行修改run_tensorboard.sh脚本内容,调整相应的参数。
    3. 您可以在浏览器访问http://<yourPublicIPAddress>:6006,查看auc曲线。auc

(可选)步骤三:制作Hive CLI、Spark CLI、dscontroller、Hue、notebook或httpd镜像

说明
  • 制作Hive CLI或Spark CLI镜像的目的是提交Hive或Spark任务进行大数据处理,生成待训练的数据,如果您已经自行准备好数据,可以跳过本步骤。如果是Spark任务,则会直接使用DataScience集群自带的Spark集群,如果是Hive任务,需要使用单独的Hadoop或Hive集群。
  • dscontroller镜像用来进行动态扩缩容。
  • Hive CLI
    进入Hive CLI目录并制作镜像。
    cd hivecli && make
  • Spark CLI
    进入Spark CLI目录并制作镜像。
    cd sparkcli && make
  • dscontroller
    进入dscontroller目录并制作镜像。
    cd dscontroller && make
  • Hue
    进入Hue目录并制作镜像。
    cd hue && make
  • notebook
    进入notebook目录并制作镜像。
    cd notebook && make
  • httpd
    进入httpd目录并制作镜像。
    cd httpd && make

步骤四:编译Pipeline

Pipeline代码具体请参见mlpipeline.py

  1. 执行以下命令,进入/ml_on_ds目录。
    sudo cd /root/dsdemo/ml_on_ds
  2. 执行以下命令,编译Pipeline。
    make mpl
    说明 您也可以执行命令sh allinone.sh,选择mpl来编译Pipeline。

    编译成功后生成***_mlpipeline.tar.gz文件。您可以使用文件传输工具将编译出来的***_mlpipeline.tar.gz文件,下载到本地PC,便于后续上传。

步骤五:上传Pipeline文件

  1. 进入集群详情页面。
    1. 登录阿里云E-MapReduce控制台
    2. 在顶部菜单栏处,根据实际情况选择地域和资源组
    3. 单击上方的集群管理页签。
    4. 集群管理页面,单击相应集群所在行的详情
  2. 集群基础信息页面的主机信息区域,查看公网IP地址。
    header_ip
  3. 在地址栏中,输入http://<yourPublicIPAddress>:31380,按回车键。
    说明 <yourPublicIPAddress>为您前一步骤中,获取的公网IP地址。
    使用默认的anonymous空间即可。进入后,默认页面如下。Kubeflow_index
  4. 在左侧导航栏,单击Pipelines
  5. Pipelines页面,单击Upload pipelineupload
  6. Upload Pipeline or Pipeline Version,输入Pipeline Name,选择编译出的文件。
    upload
  7. 单击Create

步骤六:创建并运行Experiments

  1. 在Kubeflow的左侧导航栏,单击Experiments
  2. 单击上方的Create experiment
  3. New experiment页面,输入Experiment name
  4. 单击Next
  5. Start a run页面,配置参数。
    1. 选择步骤四:编译Pipeline下载到本地的文件。
      Select_JAR
    2. 单击Recurring
      run type
  6. 单击Start

(可选)步骤七:查看Pipeline状态

您可以在Experiments中查看Pipeline状态,模型示例展示如下。see_pipeline

步骤八:模型预测

  • (推荐)使用HTTP请求方式

    此方式支持任何开发语言。预测代码请参见predict_rest.sh文件。

    您可以执行以下命令进行模型预测。
    重要 代码中的default是default命令空间,easyrec-tfserving为部署Serving用的默认名称,请您按需调整。
    !/bin/sh
    curl -X POST http://127.0.0.1:31380/seldon/default/easyrec-tfserving/api/v1.0/predictions -H 'Content-Type: application/json' -d '
    { 
    "jsonData": { 
        "inputs": {
            "app_category":["10","10"],
            "app_domain":["1005","1005"],
            "app_id":["0","0"],
            "banner_pos":["85f751fd","4bf5bbe2"],
            "c1":["c4e18dd6","6b560cc1"],
            "c14":["50e219e0","28905ebd"],
            "c15":["0e8e4642","ecad2386"],
            "c16":["b408d42a","7801e8d9"],
            "c17":["09481d60","07d7df22"],
            "c18":["a99f214a","a99f214a"],
            "c19":["5deb445a","447d4613"],
            "c20":["f4fffcd0","cdf6ea96"],
            "c21":["1","1"],
            "device_conn_type":["0","0"],
            "device_id":["2098","2373"],
            "device_ip":["32","32"],
            "device_model":["5","5"],
            "device_type":["238","272"],
            "hour":["0","3"],
            "site_category":["56","5"],
            "site_domain":["0","0"],
            "site_id":["5","3"]
        }
    }
    }'
    返回结果如下。
    {"jsonData":{"outputs":{"logits":[-7.20718098,-4.15874624],"probs":[0.000740694755,0.0153866885]}},"meta":{}}
  • 使用Seldon库方式
    执行以下命令,模型预测REST协议。
    python3.7 predict_rest.py
    返回信息如下。
    Response:
    {'jsonData': {'outputs': {'logits': [-2.66068792, 0.691401482], 'probs': [0.0653333142, 0.66627866]}}, 'meta': {}}
    说明 预测代码请参见predict_rest.py文件。

步骤九:通过PairecEngine部署在线服务

详细信息,请参见PAI-Rec使用示例

问题反馈

如果您在使用DataScience集群过程中有任何疑问或问题,请联系我们的技术人员协助处理,同时也欢迎您使用钉钉搜索钉钉群号32497587加入钉钉群进行反馈或交流。