部署数据处理算法

本文档为数据处理算法部署的说明,通过部署对应的算法,实现天枢平台数据处理模块的算法功能。部署可以基于docker,kubernetes。

算法总览

  • annotation目标检测:负责对需要标注的数据集进行自动标注,提供平台自动标注功能的支持。

  • imageNet图像分类:负责对需要图像分类的数据集进行自动标注,提供平台图像分类支持。

  • track目标跟踪:负责对已经采样完成后的数据集执行目标跟踪操作,实现平台视频数据集的目标跟踪功能。

  • imgprocess数据增强:负责对标注完成后的图片进行数据增强操作,有去雾,增雾,对比度增强,直方图均衡化。

  • OFRecord:OFRecord 格式是 「天枢深度学习框架」原生的数据格式。此算法会在发布后的imageNet数据集下生成OFRecord格式文件供训练使用。

  • videosample视频采样:此算法负责将用户上传视频根据所设定的帧间隔进行采样,获取目标跟踪所需的图片。

  • lungsegmentation医学标注:负责将医学数据集肺部影像进行自动标注,实现器官分割功能。

  • text-classification文本标注:负责将文本数据集进行自动标注,识别文本内容的积极与否。

  • 医学标注算法dcm4chee服务(该服务暂不支持K8S方式部署)

部署方式

提供两种部署方式供选择:

  • 基于docker部署

  • 基于kubernetes部署

基于docker部署算法程序

算法部署基本要求

1、ubuntu系统 版本18.04及以上

2、包含可用显卡 显存最低4G

算法部署流程

  • 拉取代码到 NFS

    从码云拉取代码 https://gitee.com/organizations/zhijiangtianshu/projects

    创建容器时,映射宿主机 NFS 路径执行代码,因此代码需要存放在 NFS 路径下

    apt-get install git -y
    cd /nfs
    git clone https://gitee.com/zhijiangtianshu/Dubhe.git

    执行 git clone 操作时会需求用户输入码云的账号密码。

    算法所需代码路径层级为/nfs/Dubhe/dubhe_data_process(后续在启动算法容器的时候需要作为参数).

  • 创建算法镜像
$ wget http://122.224.169.50:30000/index.php/s/TzzxEq3gSr9p4Kq/download -O dubheDeployScriptfile.zip
$ unzip dubheDeployScriptfile.zip
$ cd dubheDeployScriptfile/init-algorithm/
$ docker build -t algorithm:v1 . # 在如上解压后目录中执行
  • 创建算法容器
docker run -itd --gpus all --name annotation -v /nfs:/nfs algorithm:v1 sh -c "/bin/bash","-c","mkdir /root;cd /root; rm -rf algorithm; wget http://122.224.169.50:30000/index.php/s/889aQqMNM4zWd2D/download -O algorithm.zip; apt install unzip; unzip algorithm.zip; cd /root/algorithm; chmod a+x init.sh; bash init.sh annotation /nfs/Dubhe/dubhe_data_process 127.0.0.1 '' 0 6379;"

此命令为启动自动标注算法的一个示例;

--name 后的参数为将要创建的容器名称,此处用户自行命名,更换容器名称,同一种算法可以启动多个节点,实现分布式部署提升效率;

上述脚本中的此条命令:

bash init.sh annotation /nfs/Dubhe/dubhe_data_process 127.0.0.1 '' 0 6379;
修改参数以启动指定的算法,需要用户提供算法运行的redis环境配置,命令中要传递六个参数,其中后四个参数是redis相关配置,该配置需要和项目后端服务dubhe-task里的redis配置保持一致,参数说明如下:
  • annotation 指定执行的算法
  • /nfs/Dubhe/dubhe_data_process 算法代码所在路径
  • 127.0.0.1 算法环境redis的host
  • '' 算法环境redis的password
  • 0 算法环境redis的database
  • 6379 算法环境redis的port
可选算法有八种:启动指定算法的对应参数为:
  • annotation 目标检测算法
  • imagenet 图像分类算法
  • imgprocess 数据增强算法
  • ofrecord 生成ofrecord数据格式算法
  • track 目标跟踪算法
  • videosample 视频采样算法
  • lungsegmentation 医学标注算法
  • text-classification nlp文本标注算法
创建算法容器时传入对应的参数,将会自动执行相应的启动算法命令。
  • 通过以下命令可以查看算法是否启动成功
docker logs annotation

命令中annotation为之前创建的算法容器名称

  • 若出现如下日志则说明算法启动成功
图 1 启动日志
图 1 启动日志
dcm服务部署

数据处理医学影像部分是基于dcm4chee实现的,其中影像的显示是基于开源项目dcm4chee-arc-light实现 github地址: https://github.com/dcm4che/dcm4chee-arc-light.git

通过docker方式部署该项目,具体步骤如下:

  1. 创建一个docker默认桥接网络
$ docker network create dcm4chee_default
  1. 开启OpenLDAP Server
docker run --network=dcm4chee_default --name ldap \
-p 389:389 \
-v /etc/localtime:/etc/localtime:ro \
-v /var/local/dcm4chee-arc/ldap:/var/lib/ldap \
-v /var/local/dcm4chee-arc/slapd.d:/etc/ldap/slapd.d \
-d dcm4che/slapd-dcm4chee:2.4.44-12.0

参数说明:

  • --name 容器名称: ldap
  • -p docker和宿主机的映射端口 ,前面为宿主机,后面为docker服务端口
  • -v 映射docker文件到宿主机,保证容器消失后数据不会丢失
  • -d 以后台方式的模式运行
  1. 开启PostGres DB 实例
docker run --network=dcm4chee_default --name db \
-p 5432:5432 \
-e POSTGRES_DB=pacsdb \
-e POSTGRES_USER=pacs \
-e POSTGRES_PASSWORD=pacs \
-v /etc/localtime:/etc/localtime:ro \
-v /var/local/dcm4chee-arc/db:/var/lib/postgresql/data \
-d dcm4che/postgres-dcm4chee:10.0-12

参数说明:

  • --name 容器实例名称
  • -p 容器和宿主机映射端口
  • POSTGRES_DB 数据库实例名
  • POSTGRES_USER 数据库用户名
  • POSTGRES_PASSWORD 数据库密码
  • -v 绑定数据库宿主数据文件位置,保证容器结束数据不丢失。
  1. 使用已部署的dcm4che Archive 5应用程序启动Wildfly
docker run --network=dcm4chee_default --name arc \
-p 8080:8080 \
-p 8443:8443 \
-p 9990:9990 \
-p 11112:11112 \
-p 2575:2575 \
-e POSTGRES_DB=pacsdb \
-e POSTGRES_USER=pacs \
-e POSTGRES_PASSWORD=pacs \
-e WILDFLY_WAIT_FOR="ldap:389 db:5432" \
-v /etc/localtime:/etc/localtime:ro \
-v /var/local/dcm4chee-arc/wildfly:/opt/wildfly/standalone \
-d dcm4che/dcm4chee-arc-psql:5.12.0

参数说明:

  • POSTGRES_DB 数据库实例名
  • POSTGRES_USER 数据库用户名
  • POSTGRES_PASSWORD 数据库密码
  • -v 绑定宿主机数据文件位置,保证容器结束数据不丢失。

端口说明:

  • 8080端口和8443端口是dcm服务web服务端口,其中8080(http)、8443是(https)
  • 9990端口是WildFly管理控制台的http端口
  • 11112端口和2575端口是存档应用程序的DICOM和HL7端口

部署后访问地址如下(host请替换为部署所在机器IP)

http://${host}:8080/dcm4chee-arc/ui2/#/studies
note
  • 11112端口用于admin端上传文件到dcm服务(该端口需要配置到dubhe-admin的配置文件中)
  • 2575端口暂时没用到
  • dubhe-web工程中dcm服务地址请使用如下
    http://{host}:{port}/dcm4chee/dcm4chee-arc/aets/DCM4CHEE_ADMIN

基于kubernetes部署算法程序

环境准备

  • 部署 metrics-server

    参照 部署 Metrics Server

  • 部署 promethues (在 monitoring 命名空间下)

    参照 部署 Prometheus 和 Grafana 监控 Pod 指标信息

  • 部署 custom-metrics-server

    1. pull k8s-prom-hpa

      git clone https://github.com/stefanprodan/k8s-prom-hpa
    2. Generate the TLS certificates needed by the Prometheus adapter

      cd k8s-prom-hpa
      touch metrics-ca.key metrics-ca.crt metrics-ca-config.json
      make certs
      note

      说明:
      如果你执行 make certs 报错,如下:

      Failed to load config file: {"code":5200,"message":"could not read configuration file"}Failed to parse input: unexpected end of JSON input
      make: *** [gencerts] 错误 1

      请按照下面步骤执行:

      cd 到 k8s-prom-hpa 文件下,找到 Makefile 文件,把里面的内容替换为:

      # Makefile for generating TLS certs for the Prometheus custom metrics API adapter
      SHELL=bash
      UNAME := $(shell uname)
      PURPOSE:=metrics
      SERVICE_NAME:=custom-metrics-apiserver
      ALT_NAMES:="custom-metrics-apiserver.monitoring","custom-metrics-apiserver.monitoring.svc"
      SECRET_FILE:=custom-metrics-api/cm-adapter-serving-certs.yaml
      certs: gensecret rmcerts
      .PHONY: gencerts
      gencerts:
      @echo Generating TLS certs
      @docker pull cfssl/cfssl
      @mkdir -p output
      @touch output/apiserver.pem
      @touch output/apiserver-key.pem
      @openssl req -x509 -sha256 -new -nodes -days 365 -newkey rsa:2048 -keyout $(PURPOSE)-ca.key -out $(PURPOSE)-ca.crt -subj "/CN=ca"
      @echo '{"signing":{"default":{"expiry":"43800h","usages":["signing","key encipherment","'$(PURPOSE)'"]}}}' > "$(PURPOSE)-ca-config.json"
      @echo '{"CN":"'$(SERVICE_NAME)'","hosts":[$(ALT_NAMES)],"key":{"algo":"rsa","size":2048}}' | docker run -v ${HOME}:${HOME} -v ${PWD}/metrics-ca.key:/go/src/github.com/cloudflare/cfssl/metrics-ca.key -v ${PWD}/metrics-ca.crt:/go/src/github.com/cloudflare/cfssl/metrics-ca.crt -v ${PWD}/metrics-ca-config.json:/go/src/github.com/cloudflare/cfssl/metrics-ca-config.json -i cfssl/cfssl gencert -ca='/go/src/github.com/cloudflare/cfssl/metrics-ca.crt' -ca-key='/go/src/github.com/cloudflare/cfssl/metrics-ca.key' -config='/go/src/github.com/cloudflare/cfssl/metrics-ca-config.json' - | docker run --entrypoint=cfssljson -v ${HOME}:${HOME} -v ${PWD}/output:/go/src/github.com/cloudflare/cfssl/output -i cfssl/cfssl -bare /go/src/github.com/cloudflare/cfssl/output/apiserver
      .PHONY: gensecret
      gensecret: gencerts
      @echo Generating $(SECRET_FILE)
      @echo "apiVersion: v1" > $(SECRET_FILE)
      @echo "kind: Secret" >> $(SECRET_FILE)
      @echo "metadata:" >> $(SECRET_FILE)
      @echo " name: cm-adapter-serving-certs" >> $(SECRET_FILE)
      @echo " namespace: monitoring" >> $(SECRET_FILE)
      @echo "data:" >> $(SECRET_FILE)
      ifeq ($(UNAME), Darwin)
      @echo " serving.crt: $$(cat output/apiserver.pem | base64)" >> $(SECRET_FILE)
      @echo " serving.key: $$(cat output/apiserver-key.pem | base64)" >> $(SECRET_FILE)
      endif
      ifeq ($(UNAME), Linux)
      @echo " serving.crt: $$(cat output/apiserver.pem | base64 -w 0)" >> $(SECRET_FILE)
      @echo " serving.key: $$(cat output/apiserver-key.pem | base64 -w 0)" >> $(SECRET_FILE)
      endif
      .PHONY: rmcerts
      rmcerts:
      @rm -f apiserver-key.pem apiserver.csr apiserver.pem
      @rm -f metrics-ca-config.json metrics-ca.crt metrics-ca.key
      .PHONY: deploy
      deploy:
      kubectl create -f ./namespaces.yaml
      kubectl create -f ./metrics-server
      kubectl create -f ./prometheus
      kubectl create -f ./custom-metrics-api

      然后再次执行 make certs 命令。

  1. Deploy the Prometheus custom metrics API adapter

    note

    查看 promethues 采集的信息来决定是否要修改 k8s-prom-hpa/custom-metrics-api 目录下的 custom-metrics-config-map.yaml 文件。

    如下,promethues 采集的信息中以 container = container 名称pod = pod 名称 这样的 key/value 来展现的。

    prometheus采集信息展示
    prometheus采集信息展示

    而 custom-metrics-config-map.yaml 中 container 名称对应的 key 为 container_name,pod 名称对应的 key 为 pod_name,

    如下:

    seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod_name!=""}'

    所以,需要把 custom-metrics-config-map.yaml 中所有的 container_name 替换为 container,pod_name 替换为 pod。

    如下:

    seriesQuery: '{__name__=~"^container_.*",container!="POD",namespace!="",pod!=""}'

    执行命令:

    cd k8s-prom-hpa
    kubectl apply -f custom-metrics-api/

    查看结果:

    [root@master02 ~]# kubectl get pods -n monitoring | grep custom
    custom-metrics-apiserver-6bb5c8b664-5r2mx 1/1 Running 0 3s
    [root@master02 ~]#

    当出现如下结果,则安装成功

    [root@master02 ~]# kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq . | grep accelerator_duty_cycle
    "name": "namespaces/accelerator_duty_cycle",
    "name": "pods/accelerator_duty_cycle",
    [root@master02 ~]#
    note

    只有包含gpu的节点才有 accelerator_duty_cycle 指标,上述查询结果为空可改为

    kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq . | grep cpu

    若查询有结果,则说明到此为止部署正确。但是后续的部分算法部署是需要 gpu 支持的。

算法运行环境搭建

note

特别提醒:
快速部署前要保证所在服务器 NFS 已经配置完成,且服务器有 gpu

  • 拉取代码到 NFS

首先进入 NFS 路径,拉取 Dubhe git 仓库最新源码至本地;

创建容器时,映射宿主机 NFS路径执行代码,因此代码需要存放在 NFS 路径下

算法所需代码路径层级为 /nfs/Dubhe/dubhe_data_process(后续在启动算法容器的时候需要作为参数)

  • 创建算法镜像
$ wget http://122.224.169.50:30000/index.php/s/TzzxEq3gSr9p4Kq/download -O dubheDeployScriptfile.zip
$ unzip dubheDeployScriptfile.zip
$ cd dubheDeployScriptfile/init-algorithm/
$ docker build -t algorithm:v1 . # 在如上解压后目录中执行
  • 创建算法容器
note

特别提醒:
在执行 yaml 文件之前,你需要根据自己的实际情况来调整相关参数。

以 algorithm-annotation.yaml 和 algorithm-annotation-hpa.yaml 为例:

  • algorithm-annotation.yaml

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: algorithm-annotation
    spec:
    selector:
    matchLabels:
    app: algorithm-annotation
    replicas: 2
    template:
    metadata:
    labels:
    app: algorithm-annotation
    annotations:
    prometheus.io/scrape: "true"
    spec:
    terminationGracePeriodSeconds: 60
    containers:
    - name: algorithm-annotation
    image: algorithm:v1
    imagePullPolicy: IfNotPresent
    lifecycle:
    preStop:
    exec:
    command: ["/bin/sh","-c","cd /root/algorithm; chmod a+x stop.sh; bash stop.sh; sleep 60"]
    command: ["/bin/bash","-c","cd /root; rm -rf algorithm; wget http://122.224.169.50:30000/index.php/s/889aQqMNM4zWd2D/download -O algorithm.zip; apt install unzip; unzip algorithm.zip; cd /root/algorithm; chmod a+x init.sh; bash init.sh annotation /nfs/Dubhe/dubhe_data_process 10.5.18.239 '' 0 6379"]
    volumeMounts:
    - name: algorithm-annotation-nfs
    mountPath: /nfs
    ports:
    - containerPort: 9898
    protocol: TCP
    resources:
    requests:
    cpu: "1000m"
    memory: "2Gi"
    nvidia.com/gpu: "0"
    limits:
    cpu: "2000m"
    memory: "4Gi"
    nvidia.com/gpu: "0"
    volumes:
    - name: algorithm-annotation-nfs
    nfs:
    server: 10.5.26.234
    path: /nfs

    你需要根据实际情况来调整如下参数:

    1. spec.replicas

    2. spec.template.spec.containers.command

      本例中,执行的命令为:

      bash init.sh annotation /nfs/Dubhe/dubhe_data_process 10.5.18.239 '' 0 6379;

      传递了六个参数,其中后四个参数是redis相关配置,该配置需要和项目后端服务dubhe-task里的redis配置保持一致,参数说明如下:

      • annotation:执行的算法

      • /nfs/Dubhe/dubhe_data_process:代码位置

      • 10.5.18.239:算法对应环境 redis 的 host

      • "":算法对应环境 redis 的 password

      • 0:算法对应环境 redis 的 database

      • 6379:算法对应环境 redis 的 port

        比如,你想启动增强算法,则需如下修改:

        bash init.sh enhance /nfs/Dubhe/dubhe_data_process 10.5.18.239 '' 0 6379;
    3. spec.template.spec.containers.volumeMounts 指定容器内部映射路径

    4. spec.template.spec.containers.resources 指定为容器分配的资源

    5. spec.template.spec.volumes 指定 nfs 路径

  • algorithm-annotation-hpa.yaml

    ---
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    metadata:
    name: algorithm-annotation
    spec:
    scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: algorithm-annotation
    minReplicas: 2
    maxReplicas: 4
    metrics:
    - type: Resource
    resource:
    name: cpu
    target:
    type: Utilization
    averageUtilization: 70
    - type: Pods
    pods:
    metric:
    name: accelerator_duty_cycle
    target:
    type: AverageValue
    averageValue: 30

    你需要根据实际情况来调整如下参数:

    1. spec.minReplicas: 缩容后最小的 pod 个数

    2. spec.maxReplicas:扩容后最大的 pod 个数

    3. spec.metrics:扩缩容指标

      本例中,表示 CPU 使用率超过 70% 或者 GPU 使用率超过 30% 后会进行扩容

cd dubheDeployScriptfile/init-algorithm/
# 标注算法
kubectl apply -f algorithm-annotation.yaml
kubectl apply -f algorithm-annotation-hpa.yaml
# ofrecord 数据转换算法
kubectl apply -f algorithm-ofrecord.yaml
kubectl apply -f algorithm-ofrecord-hpa.yaml
# imagenet 算法
kubectl apply -f algorithm-imagenet.yaml
kubectl apply -f algorithm-imagenet-hpa.yaml
# 增强算法
kubectl apply -f algorithm-imgprocess.yaml
kubectl apply -f algorithm-imgprocess-hpa.yaml
# 目标跟踪算法
kubectl apply -f algorithm-track.yaml
# videosample 算法
kubectl apply -f algorithm-videosample.yaml
kubectl apply -f algorithm-videosample-hpa.yaml
# 医学标注算法算法
kubectl apply -f algorithm-lungsegmentation.yaml
kubectl apply -f algorithm-lungsegmentation-hpa.yaml
# nlp文本标注算法
kubectl apply -f algorithm-text-classification.yaml
kubectl apply -f algorithm-text-classification-hpa.yaml

等待 pod 全部变为 running 状态。

Last updated on