前言
實驗室的機器最近關掉了,只有用集群跑實驗。搜集了很多資料,整理成了本文。旨在提供polyaxon的快速使用方法和一些關於docker,k8s的食譜。如何安裝和部署polyaxon可以查看參考資料中的相關鏈接。推薦先跳到最后看參考資料部分的說明。
Polyaxon 介紹

A platform for reproducing and managing the whole life cycle of machine learning and deep learning applications.
這是來自官方文檔的介紹。就我理解而言,polyaxon依靠k8s部署在集群上,可以自主分配需要集群資源,創建簡單,可重復,可移植的部署,依靠docker定制運行環境,用於大規模深度學習和機器學習訓練。
它提供了一些特性:調度多個實驗或者多組實驗(用於不同參數實驗的比較或者大規模調參),監控資源和狀態,跟蹤參數,日志,配置和標簽,向用戶報告指標,輸出和其他結果。
同時,它還提供了一些超參數調優算法進行大規模調參,以及方便的Notebook,Tensorboard。
我們用Polyaxon來干嘛
我們可以通過Polyaxon上傳本地代碼到集群,然后通過寫polyaxon配置文件,定制我們所需要的docker鏡像,所需要的資源(內存,CPU,GPU),以及實驗類型(jupyter notebook, tensorboard 或者 普通實驗)等選項來創建一個或者一組實驗(運行在集群指定節點的一個個容器里面),同時通過web界面的dashboard或者polyaxon-cli提供的眾多命令監控資源和狀態,跟蹤參數,日志,配置和標簽,以及最終的結果和輸出等。

k8s 介紹
Kubernetes (簡稱k8s) 將一個網絡中的多個機器管理成一個集群,分為主節點(master)和其他節點(Node)。它可以把用戶提交的容器(Container)放到其管理的集群的某一台節點(Node)上去,並根據容器大小規格自動調度並分配相應的資源。主節點負責管理所有節點的相關狀態,下發給其他節點命令並執行等。
!!! quote
K8s 的 Node 是真正運行業務負載的,每個業務負載會以 Pod 的形式運行。一個 Pod 中運行着一個或者多個容器,真正去運行這些 Pod 的組件的是叫做 kubelet,它接收到所需要 Pod 運行的狀態,然后提交到 Container Runtime 組件中。 ----《從零開始入門 K8s| 阿里技術專家詳解 K8s 核心概念》

另外一個需要了解的概念是volume (卷)。
它是用來管理 Kubernetes 存儲的,是用來聲明在 Pod 中的容器可以訪問文件目錄的,一個卷可以被掛載在 Pod 中一個或者多個容器的指定路徑下面。----《從零開始入門 K8s| 阿里技術專家詳解 K8s 核心概念》
容器實際一次運行結束后,除非將數據保存在永久存儲卷中,否則數據會丟失。因此k8s將一定的本地存儲空間掛載在容器中,成為一個可訪問目錄。容器運行時產生的數據可以存儲在這個卷中。
接下來我們介紹k8s和polyaxon的聯系。
polyaxon被部署在k8s上,使用polyaxon創建一個或者一組實驗時,會根據配置文件創建一個或者多個容器由k8s實際調度運行在集群的某個或多個節點上。k8s負責其資源的調度,狀態的監控等。也就是說,polyaxon實際提供了一個更加上層的接口,不需要用戶自己執行任何k8s的命令來創建容器,創建Pod, 運行bash,輸出狀態信息等。這一切的一切都可以通過polyaxon完成。
正如上文所言,polyaxon 要指定路徑來進行持久存儲(persistence storage),不然實驗數據和實驗結果在容器運行結束后都無法保存了。因此,我們可以指定一台節點上的某幾個文件夾作為掛載到容器的永久存儲卷。
這些文件夾在本地的路徑以及容器上掛載的別名可以通過查看polyaxonpolyaxon-config.yml得知

比如上圖:定義了如下的持久存儲卷(注:PVC: PersistentVolumeClaim):
polyaxon-pvc-logs(默認掛載為logs) 用於保存實驗的日志polyaxon-pvc-repos(默認掛載為code) ,上傳的代碼將保存在這里polyaxon-pvc-data(默認掛載為data),一些大數據集可以事先上傳到這個文件夾中,故不需要在上傳代碼時費時上傳很大的數據集polyaxon-pvc-outputs(默認掛在為outputs) , 實驗的輸出和模型斷點保存在該文件夾中
k8s 常用命令
k8s提供了kubectl 命令行工具對集群進行管理。我們可以登錄master節點,利用該工具執行命令。
一些常用命令總結如下:
# 查看所有節點/Pod
$ kubectl get nodes/pods
# 查看指定節點/Pod的詳細信息
$ kubectl describe nodes/pods [name]
# 在一個pod的運行的某個容器(如果只有一個,則省略-c部分)中獲取shell
$ kubectl exec -it [pod-name] -c [container-name] -- /bin/bash
# 列出每個節點GPU的使用情況
# 目前無法列出具體GPU的編號,但是我認為這部分是由k8s管理起來了,即自動調度可用的GPU
$ kubectl describe nodes | tr -d '\000' | sed -n -e '/^Name/,/Roles/p' -e '/^Capacity/,/Allocatable/p' -e '/^Allocated resources/,/Events/p' | grep -e Name -e nvidia.com | perl -pe 's/\n//' | perl -pe 's/Name:/\n/g' | sed 's/nvidia.com\/gpu:\?//g' | sed '1s/^/Node Available(GPUs) Used(GPUs)/' | sed 's/$/ 0 0 0/' | awk '{print $1, $2, $3}' | column -t
# 顯示目前GPU的情況:利用polyaxon的notebook執行nvidia-smi, 或者在運行的容器里面呼出shell, 或者使用polyaxon的gpu監測命令來監視GPU內存使用情況
接下來解釋一下kubectl describe nodes/pods [name] 輸出的信息。
# describe部分輸出信息說明:
# Capacity: 容量; Allocatable: 可分配; Allocated:已分配
# cpu: 56 # cpu核心數
# cpu: 55900m # 100m=0.1個cpu核心,故這里指55.9個cores
# ephemeral-storage: 臨時存儲空間; 以字節為基本單位
# memory: 內存
# nvidia.com/gpu: 有/可分配gpu數
# hugepages-2Mi: 80Mi : 分配的大頁面可以超過4KiB的默認頁面大小,若分配大小超過為40個2Mi(共80Mi)的大頁面則分配失敗
# requests: 該node/pod/container需要的資源大小
# limits: 該node/pod/container最大可分配資源大小
# requests: 625m(1%) : 百分比例含義: 625m/55900m=1%
Polyaxon 快速上手
$ pip install -U polyaxon-cli #安裝polyaxon-cli
# 配置polyaxon
$ polyaxon config -l #列出當前配置
$ polyaxon config set --host=[ip] --port=[port]
# 登錄
$ polyaxon login -u [username] -p [password] #注意如果是內網映射到外網,要設置終端代理
# 檢查是否正運行與平台兼容的CLI版本
$ polyaxon version --cli
$ polyaxon version --platform
# 檢查是否登錄
$ polyaxon whoami
# 創建項目
#【example】
$ polyaxon project create --name=quick-start --description="Polyaxon quick start."
$ git clone https://github.com/polyaxon/polyaxon-quick-start.git
$ cd polyaxon-quick-start
# 使用在Polyaxon中創建項目時使用的名稱初始化項目,並生成默認的配置文件polyaxonfile.yaml
$ polyaxon init quick-start --polyaxonfile
注:polyaxon-cli 是管理polyaxon的命令行工具,我們同樣也可以通過web界面的dashborad來創建項目等。
接下來,我們需要寫配置文件,描述實驗,實驗組,作業,插件應如何在Polyaxon上運行。
以下提供了一個示例polyaxonfile.yaml和相關解釋
version: 1 # 指定使用的polyaxon版本,無關緊要的參數,默認就好
kind: experiment # 操作的類型,除此之外,還有notebook,tensorboard,group等
environment:
node_selector: # 選擇集群中哪個節點來運行該實驗
kubernetes.io/hostname: gpu-a # 節點名
resources: # 要求的資源 (cpu,內存,GPU等),一般是GPU
gpu: # 注:在GPU調度中k8s要求requests和limits必須相同
requests: 1 # 目前要求的
limits: 1 # 最大限制
# 構建部分將構建一個docker映像,在本例中,我們希望使用指定的tensorflow docker映像運行我們的代碼。我們還安裝了用於跟蹤和在實驗結束時發送metrics的polyaxon-client
build:
image: tensorflow/tensorflow:1.4.1-py3
build_steps:
- pip3 install polyaxon-client # polyaxon的python包
run: #執行代碼
cmd: python model.py
接下來即上傳和運行代碼
# update code
$ polyaxon upload
# start an experiment
$ polyaxon run
# 上面兩條可以合成一條
$ polyaxon run -u
Polyaxon 常用命令
# 列出該項目的所有實驗
$ polyaxon project experiments
# 檢查實驗日志
$ polyaxon experiment -xp [exp-id] get
# 開始另一個實驗
$ polyaxon run -f [實驗配置文件.yaml]
# 開始一組實驗(比如調參時用)
# 檢查實驗配置文件是否有效
$ polyaxon check -f polyaxonfile_hyperparams.yaml --definition
# 開始一組實驗
$ polyaxon run -f polyaxonfile_hyperparams.yaml
# check這組實驗的相關信息
$ polyaxon group -g [group-id] get # 這個組的整體信息
$ polyaxon group -g [group-id] experiments # 這個組的所有實驗的信息
$ polyaxon group -g [group-id] experiments -m # 這個組所有實驗的metric
$ polyaxon group -g [group-id] experiments -p # 這個組所有實驗的參數
# 過濾指定信息
$ polyaxon group -g [group-id] experiments -m -q "status:succeeded, params.activation:relu|sigmoid, metrics.loss:<=0.3"
# Dashboard
$ polyaxon dashboard
# tensorboard
# 可以為一個單獨的實驗,一個小組的所有實驗,或者一個項目的所有實驗啟動一個tensorboard
$ polyaxon tensorboard -xp [exp-id] start -f [tensorboard配置文件]
$ polyaxon tensorboard -xp [exp-id] stop
# notebook
$ polyaxon notebook start -u -f [使用的配置文件路徑]
$ polyaxon notebook stop
命令及其參數有很多,具體可以使用--help 查看幫助
比如polyaxon notebook start --help
Polyaxon YAML填寫規范
要確保polyaxon文件有效,可以運行以下命令檢查
$ polyaxon check -f polyaxonfile.yaml -def
下面提供兩種常見的寫法
version: 1 # Represents the polyaxon file specification version. 不用管就是
kind: experiment # 操作的種類: experiment, group, job, notebook, tensorboard, pipeline
logging:
level: INFO # log level
formatter: # The log formatter regex.
environment:
node_selector: # 選擇指定節點
kubernetes.io/hostname: gpu_a
resources:
cpu:
requests: 1
limits: 2
gpu:
requests: 1
limits: 1
params:
batch_size: 128
convolutions:
conv1:
kernels: [32, 32]
size: [2, 2]
strides: [1, 1]
conv2:
kernels: [64, 64]
size: [2, 2]
strides: [1, 1]
build:
image: http://[私有倉庫ip]/nvidia/pytorch:20.01-py3 #可以使用公共鏡像也可以使用實驗室私有的
build_steps:
- pip install PILLOW
- pip install scikit-learn
# dockerfile: path/to/Dockerfile 通過dockerfile構建全新的鏡像,而不通過指定現有的鏡像
run:
cmd: python model.py --conv1_kernels="{{ convolutions.conv1.kernels }}" --conv1_stides="{{ convolutions.conv1.strides }}" --batch-size={{ batch_size }}
另一種是預先聲明了傳入參數的類型,使得在通過polyaxon-cli運行該實驗時,可以先驗證參數合法性,如果不通過,則不會運行該實驗。
version: 1
kind: experiment
inputs:
- name: batch_size
description: batch size
is_optional: true # 是否可選
default: 128
type: int
- name: num_steps
is_optional: true
default: 500
type: int
- name: learning_rate
is_optional: true
default: 0.001
type: float
- name: dropout
is_optional: true
default: 0.25
type: float
- name: num_epochs
is_optional: true
default: 1
type: int
- name: activation
is_optional: true
default: relu
type: str
build:
image: tensorflow/tensorflow:1.4.1-py3
build_steps:
- pip3 install --no-cache-dir -U polyaxon-client==0.5.0
run:
cmd: python3 model.py --batch_size={{ batch_size }} \
--num_steps={{ num_steps }} \
--learning_rate={{ learning_rate }} \
--dropout={{ dropout }} \
--num_epochs={{ num_epochs }} \
--activation={{ activation }}
更多使用方法可以查看官方文檔。
參考資料
筆者初接觸docker,k8s和polyaxon平台,行文倉促且拙劣。本文僅整理一些常用的命令方便日后使用,介紹部分有很多遺漏和謬誤,還望原諒和指正。在成文過程中參考了以下資料,比起筆者寫的這篇文章而言,我更推薦大家去閱讀這些資料 TUT
Docker部分
- 介紹Docker
8 分鍾入門 K8s | 詳解容器基本概念 - 知乎 (強烈推薦)
如何通俗解釋Docker是什么? - 知乎 (強烈推薦)
在 Windows 上可以用 Docker 嗎? - 知乎 (強烈推薦)
關於 Windows 容器 | Microsoft Docs
深挖 Docker 之 Linux namespace 和 cgroups - 知乎
- 兼顧Docker介紹和實戰
Docker -- 從入門到實踐 (強烈推薦)
k8s 部分
- k8s介紹
合集| 21 篇技術文章,帶你從零入門 K8s-阿里雲開發者社區 (強烈推薦)
從零開始入門 K8s| 阿里技術專家詳解 K8s 核心概念 - 知乎 (強烈推薦)
- k8s 使用
Kubernetes之kubectl命令行工具簡介、安裝配置及常用命令
常用kubectl命令總結 - Federico - 博客園
Kubernetes 官方文檔 (強烈推薦)
k8s 部署 Polyaxon
使用kubeadm建立kubernetes集群並部署Polyaxon詳細教程 (強烈推薦)
Polyaxon 官方文檔
入門介紹和Quick-Start (強烈推薦)
Polyaxon YAML 規范 (強烈推薦)
