Python 与 TensorFlow2 生成式 AI(一)(1)https://developer.aliyun.com/article/1512061
重要的 Docker 命令和语法
要了解 Docker 的工作原理,了解用于所有 Docker 容器的模板Dockerfile是有用的。作为示例,我们将使用 Kubeflow 项目中的 TensorFlow 容器笔记本示例(链接)。
此文件是 Docker 应如何采用基本操作环境、添加依赖项并在打包后执行软件的一组说明:
FROM public.ecr.aws/j1r0q0g6/notebooks/notebook-servers/jupyter-tensorflow:master-abf9ec48 # install - requirements.txt COPY --chown=jovyan:users requirements.txt /tmp/requirements.txt RUN python3 -m pip install -r /tmp/requirements.txt --quiet --no-cache-dir \ && rm -f /tmp/requirements.txt
虽然容器之间的确切命令会有所不同,但这将让您了解我们可以如何使用容器来管理应用程序——在这种情况下,使用一致的库集运行 Jupyter 笔记本进行交互式机器学习实验。一旦我们为我们的特定操作系统安装了 Docker 运行时,我们将通过运行以下命令来执行这样一个文件:
Docker build -f <Dockerfilename> -t <image name:tag>
当我们这样做时,会发生一些事情。首先,我们从远程存储库中检索base
文件系统或 image
,这有点类似于我们在使用 Java 构建工具(如 Gradle 或 Maven)或 Python 的 pip 安装程序时,从 Artifactory 收集 JAR 文件的方式。有了这个文件系统或 image
,然后我们为 Docker build
命令设置所需的变量,比如用户名和 TensorFlow 版本,以及容器的运行时环境变量。我们确定将用于运行命令的 shell 程序,然后安装我们需要运行 TensorFlow 和笔记本应用程序的依赖项,并指定在启动 Docker 容器时要运行的命令。然后,我们使用由基本 image 名称
和一个或多个 tags
(比如版本号,或者在许多情况下,简单地用时间戳来唯一标识这个 image)组成的标识符保存这个快照。最后,要实际启动运行这个容器的笔记本服务器,我们将发出以下命令:
Docker run <image name:tag>
默认情况下,Docker 会运行在 Dockerfile
文件中的可执行命令;在我们目前的示例中,这是启动笔记本服务器的命令。然而,并非一定如此;我们也可以有一个 Dockerfile
,它只是为应用程序构建一个执行环境,并发出在该环境内运行的命令。在这种情况下,命令看起来会像这样:
Docker run <image name:tag> <command>
Docker
run 命令允许我们测试我们的应用程序是否可以成功在 Dockerfile
指定的环境中运行;然而,通常我们希望在云中运行此应用程序,以便利用分布式计算资源或能够托管向全球公开的 Web 应用程序,而不是在本地。要做到这一点,我们需要将构建的镜像移到一个远程存储库,使用 push 命令,这个远程存储库可能与我们最初拉取初始镜像的存储库相同,也可能不同。
Docker push <image name:tag>
注意,image 名称可以包含对特定注册表的引用,比如本地注册表或在主要云提供商(如 AWS 的 弹性容器服务(ECS),Azure 的 Azure Kubernetes 服务(AKS) 或 Google 的容器注册表)上托管的注册表。将镜像发布到远程注册表允许开发人员共享镜像,并使我们可以在云中部署容器。
使用 Docker-compose 连接 Docker 容器
到目前为止,我们只讨论了一些基本的 Docker 命令,这些命令可以让我们在单个容器中运行单个服务。然而,你也许能够理解,在“现实世界”中,我们通常需要同时运行一个或多个应用程序 – 例如,一个网站将同时有一个获取和处理用户活动数据的网络应用程序和一个用于记录信息的数据库实例。在复杂的应用程序中,网站甚至可能由多个专门用于特定用例的小型网络应用程序或微服务组成,比如前端、用户数据或订单管理系统。对于这些类型的应用程序,我们需要多个容器彼此通信。Docker-compose 工具(docs.docker.com/compose/
)就是为此类应用程序而设计的:它允许我们使用YAML
格式在应用文件中指定多个 Docker 容器。例如,一个具有 Redis 数据库实例的网站配置可能如下:
version: '3' services: web: build: . ports: - "5000:5000" volumes: - .:/code - logvolume01:/var/log links: - redis redis: image: redis volumes: logvolume01: {}
代码 2.1:Docker Compose 的 yaml 输入文件
这里的两个应用程序容器分别是web
和redis
数据库。文件还指定了与这两个应用程序相关联的卷(磁盘)。使用这个配置,我们可以运行以下命令:
docker-compose up
这将启动 YAML 文件中指定的所有容器,并允许它们彼此通信。然而,即使 Docker 容器和 docker-compose 允许我们使用一致的执行环境构建复杂的应用程序,当我们将这些服务部署到云端时,我们可能会遇到鲁棒性问题。例如,在一个网站应用程序中,我们无法保证应用程序运行的虚拟机会持续长时间,因此我们需要管理自愈和冗余的进程。这也与分布式机器学习流水线有关,其中我们不希望因为集群中的一个节点出现问题就不得不终止整个作业,因此我们需要备份逻辑来重新启动工作的一部分。此外,虽然 Docker 具有 docker-compose 功能来链接应用程序中的几个容器,但它没有健壮的规则来控制这些容器之间的通信,或者如何将它们作为一个单元进行管理。出于这些目的,我们转向 Kubernetes 库。
Kubernetes:强大的多容器应用程序管理
Kubernetes 项目-有时缩写为 k8s-诞生于谷歌内部称为Borg的容器管理项目。Kubernetes 来自希腊词 navigator,如项目标识的七条辐射轮所示。¹⁸ Kubernetes 使用 Go 编程语言编写,提供了一个强大的框架,在由云提供商管理的底层资源上部署和管理 Docker 容器应用程序(例如亚马逊网络服务(AWS)、Microsoft Azure 和Google 云平台(GCP))。
Kubernetes 基本上是用来控制由一个或多个部署在云中的 Docker 容器组成的应用程序的工具;这个容器的集合称为Pod。每个 Pod 可以有一个或多个副本(以实现冗余),这称为资源副本集。Kubernetes 部署的两个主要组件是控制平面和节点。控制平面承载了部署和管理 Pod 的集中逻辑,由(图 2.4)组成:
图 2.4:Kubernetes 组件¹⁸
- Kube-api-server:这是主要的应用程序,它侦听用户的命令以部署或更新 Pod,或通过
ingress
管理对 Pod 的外部访问。 - Kube-controller-manager:管理每个 Pod 副本数量等功能的应用程序。
- Cloud-controller-manager:管理特定于云提供商的功能。
- Etcd:维护不同 Pod 的环境和状态变量的键值存储。
- Kube-scheduler:负责找到运行 Pod 的工作进程的应用程序。
虽然我们可以设置自己的控制平面,但在实践中,通常我们会将此功能由我们的云提供商管理,例如谷歌的Google Kubernetes 引擎(GKE)或亚马逊的弹性 Kubernetes 服务(EKS)。Kubernetes 节点-集群中的各个单独的机器-每个都运行一个名为kubelet的应用程序,该应用程序监视运行在该节点上的 Pod。
现在,我们已经对 Kubernetes 系统有了一个高层次的了解,接下来让我们来看一下你将需要与 Kubernetes 集群进行交互、更新其组件以及启动和停止应用程序的重要命令。
重要的 Kubernetes 命令
为了与在云中运行的 Kubernetes 集群进行交互,我们通常使用Kubernetes 命令行工具(kubectl)。有关在您的操作系统上安装 kubectl 的说明可以在kubernetes.io/docs/tasks/tools/install-kubectl/
找到。要验证您是否成功安装了 kubectl,可以在终端中再次运行help
命令:
kubectl --help
与 Docker 一样,kubectl 有许多命令;我们将使用的一个重要命令是apply
命令,它与docker-compose
类似,它将一个 YAML 文件作为输入并与 Kubernetes 控制平面通信以启动、更新或停止 Pod:
kubectl apply -f <file.yaml>
作为 apply
命令运行方式的示例,让我们看一下用于部署 web 服务器 (nginx
) 应用程序的 YAML 文件:
apiVersion: v1 kind: Service metadata: name: my-nginx-svc labels: app: nginx spec: type: LoadBalancer ports: - port: 80 selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
此文件中指定的资源将按照文件中列出的顺序在 Kubernetes 集群节点上创建。首先,我们创建负载均衡器,它在nginx
web 服务器的副本之间路由外部流量。metadata
用于为这些应用程序打标签,以便稍后使用 kubectl 进行查询。其次,我们使用一致的容器(镜像为 1.7.9
)创建一组 3
个 nginx
pod 的副本,它们分别使用其容器上的端口 80
。
Kubernetes 集群的同一组物理资源可以在多个虚拟集群中共享,使用命名空间 – 这使我们可以将资源分隔到多个用户或组之间。例如,这可以让每个团队运行自己的一组应用程序,并在逻辑上表现得好像他们是唯一的用户。稍后,在我们对 Kubeflow 的讨论中,我们将看到如何使用此功能在同一 Kubeflow 实例上逻辑分区项目。
用于配置管理的 Kustomize
像大多数代码一样,我们最终可能希望将用于向 Kubernetes 发出命令的 YAML 文件存储在版本控制系统中,例如 Git。这导致一些情况下这种格式可能不理想:例如,在机器学习管道中,我们可能执行超参数搜索,其中相同的应用程序以稍微不同的参数运行,导致大量重复的命令文件。
或者,我们可能有一些参数,例如 AWS 账户密钥,出于安全原因,我们不希望将其存储在文本文件中。我们还可能希望通过将我们的命令拆分为 base
和附加部分来增加重用性;例如,在 代码 2.1 中显示的 YAML 文件中,如果我们想要在不同的数据库中运行 ngnix,或者指定 Amazon、Google 和 Microsoft Azure 提供的不同云对象存储中的文件存储。
对于这些用例,我们将使用 Kustomize 工具(kustomize.io
),也可通过 kubectl 使用:
kubectl apply -k <kustomization.yaml>
或者,我们可以使用 Kustomize 命令行工具。kustomization.yaml
是一个 Kubernetes 应用程序的模板;例如,考虑以下模板,用于 Kubeflow 示例存储库中的训练作业(github.com/kubeflow/pipelines/blob/master/manifests/kustomize/sample/kustomization.yaml
):
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: # Or # github.com/kubeflow/pipelines/manifests/kustomize/env/gcp?ref=1.0.0 - ../env/gcp # Kubeflow Pipelines servers are capable of # collecting Prometheus metrics. # If you want to monitor your Kubeflow Pipelines servers # with those metrics, you'll need a Prometheus server # in your Kubeflow Pipelines cluster. # If you don't already have a Prometheus server up, you # can uncomment the following configuration files for Prometheus. # If you have your own Prometheus server up already # or you don't want a Prometheus server for monitoring, # you can comment the following line out. # - ../third_party/prometheus # - ../third_party/grafana # Identifier for application manager to apply ownerReference. # The ownerReference ensures the resources get garbage collected # when application is deleted. commonLabels: application-crd-id: kubeflow-pipelines # Used by Kustomize configMapGenerator: - name: pipeline-install-config env: params.env behavior: merge secretGenerator: - name: mysql-secret env: params-db-secret.env behavior: merge # !!! If you want to customize the namespace, # please also update # sample/cluster-scoped-resources/kustomization.yaml's # namespace field to the same value namespace: kubeflow #### Customization ### # 1\. Change values in params.env file # 2\. Change values in params-db-secret.env # file for CloudSQL username and password # 3\. kubectl apply -k ./ ####
我们可以看到此文件引用了位于相对路径 ../base
的单独的 kustomization.yaml
文件中的 base
配置集。要编辑此文件中的变量,例如,要更改应用程序的命名空间,我们将执行:
kustomize edit set namespace mykube
我们还可以添加配置映射以传递给训练作业,使用键-值格式,例如:
kustomize edit add configmap configMapGenerator --from-literal=myVar=myVal
最后,当我们准备在 Kubernetes 上执行这些命令时,我们可以动态地build
并应用所需的kubectl
命令,假设kustomization.yaml
在当前目录中。
kustomize build . |kubectl apply -f -
希望这些示例演示了 Kustomize 如何提供一种灵活的方式来使用模板生成我们在本书后面的工作流程中经常需要的 kubectl YAML;我们将经常利用它来参数化我们的工作流程。
现在我们已经了解了 Kubernetes 如何在云中管理 Docker 应用程序,以及 Kustomize 如何允许我们灵活地重用kubectl yaml
命令,让我们看看这些组件如何在 Kubeflow 中联系在一起,以运行我们稍后将进行的创建 TensorFlow 生成式 AI 模型的实验。
Kubeflow:一个端到端的机器学习实验室
正如本章开始时所描述的,端到端机器学习研究和开发的lab
有许多组件(表 2.1),例如:
- 管理和版本化库依赖,例如 TensorFlow,并将其打包为可复现的计算环境
- 可视化数据并尝试不同设置的交互式研究环境
- 指定管道步骤的系统化方式 – 数据处理、模型调优、评估和部署
- 分布式运行建模过程所需资源的供应
- 具有快照历史版本的研究过程的强大机制
正如我们在本章前面所描述的,TensorFlow 被设计用于利用分布式资源进行训练。为了利用这一能力,我们将使用 Kubeflow 项目。Kubeflow 建立在 Kubernetes 之上,具有几个在管理端到端机器学习应用程序过程中有用的组件。要安装 Kubeflow,我们需要拥有现有的 Kubernetes 控制平面实例,并使用 kubectl 启动 Kubeflow 的各个组件。设置步骤会略有不同,取决于我们是使用本地实例还是主要云服务提供商之一。
通过 MiniKF 在本地运行 Kubeflow
如果我们想快速开始或在本地原型化我们的应用程序,我们可以避免设置云账户,而是使用虚拟机模拟我们在云中配置资源的方式。要在本地设置 Kubeflow,我们首先需要安装 VirtualBox (www.virtualbox.org/wiki/Downloads
) 以运行虚拟机,以及 Vagrant 以在 VirtualBox 虚拟机上运行配置,用于设置 Kubernetes 控制平面和 Kubeflow(www.vagrantup.com/downloads.html
)。
安装了这两个依赖项后,创建一个新目录,切换到该目录并运行:
vagrant init arrikto/minikf vagrant up
这将初始化 VirtualBox 配置并启动应用程序。现在,您可以导航到http://10.10.10.10/
并按照说明启动 Kubeflow 和 Rok(Arrikto 创建,用于 Kubeflow 实验中使用的数据的存储卷)。一旦这些被提供,你应该看到一个像这样的屏幕(图 2.5):
图 2.5:在虚拟盒子中的 MiniKF 安装界面¹⁹
登录到 Kubeflow 查看各个组件的仪表板(图 2.6):
图 2.6:MiniKF 中的 Kubeflow 仪表板
我们将在后面回到这些组件,并了解 Kubeflow 提供的各种功能,但首先,让我们一起看看如何在云中安装 Kubeflow。
在 AWS 中安装 Kubeflow
在 AWS 上运行 Kubeflow,我们需要在云中提供一个 Kubernetes 控制平面。幸运的是,亚马逊提供了一个名为 EKS 的托管服务,它可以方便地提供一个控制平面来部署 Kubeflow。按照以下步骤在 AWS 上部署 Kubeflow:
- 注册 AWS 账户并安装 AWS 命令行界面
这是与各种 AWS 服务进行交互所需的,根据您平台上的说明位于docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
。安装完成后,输入:
aws configure
- 为了设置您的账户和密钥信息来提供资源。
- 安装 eksctl
这个命令行实用程序允许我们从命令行在亚马逊中提供一个 Kubernetes 控制平面。按照docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
上的说明进行安装。 - 安装 iam-authenticator
为了允许 kubectl 与 EKS 进行交互,我们需要使用 IAM 验证器提供正确的权限来修改我们的 kubeconfig。请参考docs.aws.amazon.com/eks/latest/userguide/install-aws-iam-authenticator.html
上的安装说明。 - 下载 Kubeflow 命令行工具
链接位于 Kubeflow 发布页面(github.com/kubeflow/kubeflow/releases/tag/v0.7.1
)。下载其中一个目录,并使用以下命令解压 tarball:
tar -xvf kfctl_v0.7.1_<platform>.tar.gz
- 构建配置文件
输入 Kubeflow 应用程序目录(${KF_DIR}
)、部署名称(${KF_NAME}
)和部署的基本配置文件的路径(${CONFIG_URI}
)的环境变量,位于raw.githubusercontent.com/kubeflow/manifests/v0.7-branch/kfdef/kfctl_aws.0.7.1.yaml
用于 AWS 部署,运行以下命令生成配置文件:
mkdir -p ${KF_DIR} cd ${KF_DIR} kfctl build -V -f ${CONFIG_URI}
- 这将在本地生成一个名为
kfctl_aws.0.7.1.yaml
的本地配置文件。如果这看起来像 Kustomize,那是因为kfctl
在内部使用 Kustomize 来构建配置。我们还需要为本地配置文件的位置添加一个环境变量${CONFIG_FILE}
,在这种情况下是:
export CONFIG_FILE=${KF_DIR}/kfctl_aws.0.7.1.yaml
- 在 EKS 上启动 Kubeflow
使用以下命令启动 Kubeflow:
cd ${KF_DIR} rm -rf kustomize/ kfctl apply -V -f ${CONFIG_FILE}
- 所有 Kubeflow 组件变为可用将需要一些时间;您可以通过使用以下命令来检查进度:
kubectl -n kubeflow get all
- 一旦它们都可用,我们可以使用以下命令获取 Kubeflow 仪表板的 URL 地址:
kubectl get ingress -n istio-system
这将带我们到上面的 MiniKF 示例中显示的仪表盘视图。请注意,在默认配置中,此地址对公众开放;对于安全应用程序,我们需要按照www.kubeflow.org/docs/aws/authentication/
中的说明添加身份验证。
在 GCP 中安装 Kubeflow
像 AWS 一样,Google 云平台(GCP)提供了一个托管的 Kubernetes 控制平面 GKE。我们可以使用以下步骤在 GCP 中安装 Kubeflow:
- 注册 GCP 账户并在控制台上创建一个项目
该项目将是与 Kubeflow 相关的各种资源所在的位置。 - 启用所需服务在 GCP 上运行 Kubeflow 所需的服务包括:
- 计算引擎 API
- Kubernetes 引擎 API
- 身份和访问管理(IAM)API
- 部署管理器 API
- 云资源管理器 API
- 云文件存储 API
- AI 平台培训和预测 API
- 设置 OAuth(可选)
如果您希望进行安全的部署,那么,与 AWS 一样,您必须按照说明添加身份验证到您的安装中,位于(www.kubeflow.org/docs/gke/deploy/oauth-setup/
)。或者,您可以只使用 GCP 账户的用户名和密码。 - 设置 GCloud CLI
这类似于前一节中涵盖的 AWS CLI。安装指南可在cloud.google.com/sdk/
找到。您可以通过运行以下命令来验证您的安装:
gcloud --help
- 下载 Kubeflow 命令行工具
链接位于 Kubeflow 发行版页面(github.com/kubeflow/kubeflow/releases/tag/v0.7.1
)。下载其中一个目录并使用以下命令解压 tar 文件:
tar -xvf kfctl_v0.7.1_<platform>.tar.gz
- 登录 Google 云并创建用户凭据
接下来,我们需要创建一个登录账户和凭据令牌,用于与我们的账户中的资源进行交互。
gcloud auth login gcloud auth application-default login
- 设置环境变量并部署 Kubeflow
与 AWS 一样,我们需要为一些关键环境变量输入值:包含 Kubeflow 配置文件的应用程序(${KF_DIR}
),Kubeflow 部署的名称(${KF_NAME}
),基本配置 URI 的路径(${CONFIG_URI}
- 对于 GCP,这是raw.githubusercontent.com/kubeflow/manifests/v0.7-branch/kfdef/kfctl_gcp_iap.0.7.1.yaml
),Google 项目的名称(${PROJECT}
)以及它所在的区域(${ZONE}
)。 - 启动 Kubeflow
与 AWS 一样,我们使用 Kustomize 构建模板文件并启动 Kubeflow:
mkdir -p ${KF_DIR} cd ${KF_DIR} kfctl apply -V -f ${CONFIG_URI}
- 一旦启动了 Kubeflow,您可以使用以下命令获取仪表板的 URL:
kubectl -n istio-system get ingress
在 Azure 上安装 Kubeflow
Azure 是微软公司的云服务,和 AWS 和 GCP 一样,我们可以利用它来安装 Kubeflow,利用在 Azure 云中驻留的 Kubernetes 控制平面和计算资源。
- 在 Azure 上注册账户
在azure.microsoft.com
注册账号-可用于实验的免费层。 - 安装 Azure 命令行实用程序
请参阅docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest
上平台的安装说明。您可以通过在本地计算机的命令行上运行以下命令来验证安装:
az
- 这应该会打印出您可以在控制台上使用的命令列表。首先,通过以下命令登录您的帐户:
az login
- 并输入您在步骤 1中注册的帐户凭据。您将被重定向到浏览器以验证您的帐户,之后您应该会看到类似以下的响应:
"You have logged in. Now let us find all the subscriptions to which you have access": … [ { "cloudName": … "id" …. … "user": { … } } ]
- 为新集群创建资源组
我们首先需要创建新应用所在的资源组,使用以下命令:
az group create -n ${RESOURCE_GROUP_NAME} -l ${LOCATION}
- 在 AKS 上创建 Kubernetes 资源
现在,在您的资源组上部署 Kubernetes 控制平面:
az aks create -g ${RESOURCE_GROUP_NAME} -n ${NAME} -s ${AGENT_SIZE} -c ${AGENT_COUNT} -l ${LOCATION} --generate-ssh-keys
- 安装 Kubeflow
首先,我们需要获取凭据以在我们的 AKS 资源上安装 Kubeflow:
az aks get-credentials -n ${NAME} -g ${RESOURCE_GROUP_NAME}
- 安装 kfctl
安装并解压缩 tarball 目录:
tar -xvf kfctl_v0.7.1_<platform>.tar.gz
- 设置环境变量
与 AWS 一样,我们需要为一些关键环境变量输入值:包含 Kubeflow 配置文件的应用程序(${KF_DIR}
),Kubeflow 部署的名称(${KF_NAME}
),和基本配置 URI 的路径(${CONFIG_URI}
- 对于 Azure,这是raw.githubusercontent.com/kubeflow/manifests/v0.7-branch/kfdef/kfctl_k8s_istio.0.7.1.yaml
)。 - 启动 Kubeflow
与 AWS 一样,我们使用 Kustomize 构建模板文件并启动 Kubeflow:
mkdir -p ${KF_DIR} cd ${KF_DIR} kfctl apply -V -f ${CONFIG_URI}
- 一旦启动 Kubeflow,您可以使用端口转发将本地端口
8080
的流量重定向到集群中的端口80
,以使用以下命令在localhost:8080
上访问 Kubeflow 仪表板:
kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80
使用 Terraform 安装 Kubeflow
对于这些云提供商,你可能会注意到我们有一套共同的命令;创建一个 Kubernetes 集群,安装 Kubeflow,并启动应用程序。虽然我们可以使用脚本来自动化这个过程,但想要像我们的代码一样,有一种方法来版本控制和持久化不同的基础设施配置,允许创建运行 Kubeflow 所需资源集合的可重现的配方,这将是可取的。这也有助于我们在不完全重写安装逻辑的情况下,潜在地在不同的云提供商之间移动。
模板语言Terraform (www.terraform.io/
)是由 HashiCorp 创建的一种用于基础设施即服务(IaaS)的工具。就像 Kubernetes 有一个 API 来更新集群上的资源一样,Terraform允许我们使用 API 和模板语言来抽象不同的底层云提供商的交互,使用命令行工具和用 GoLang 编写的核心组件。Terraform 可以使用用户编写的插件进行扩展。
图 2.7:Terraform 架构²⁰
让我们以安装 Kubeflow 在 AWS 上使用 Terraform 指南的一个例子,位于github.com/aws-samples/amazon-eks-machine-learning-with-terraform-and-kubeflow
上。一旦你在 EC2 容器上建立所需的 AWS 资源并安装了 terraform,aws-eks-cluster-and-nodegroup.tf
Terraform 文件用于使用命令创建 Kubeflow 集群:
terraform apply
这个文件中有一些关键组件。一个是指定部署方面的变量:
variable "efs_throughput_mode" { description = "EFS performance mode" default = "bursting" type = string }
另一个是指定我们正在使用的云提供商的规范:
provider "aws" { region = var.region shared_credentials_file = var.credentials resource "aws_eks_cluster" "eks_cluster" { name = var.cluster_name role_arn = aws_iam_role.cluster_role.arn version = var.k8s_version vpc_config { security_group_ids = [aws_security_group.cluster_sg.id] subnet_ids = flatten([aws_subnet.subnet.*.id]) } depends_on = [ aws_iam_role_policy_attachment.cluster_AmazonEKSClusterPolicy, aws_iam_role_policy_attachment.cluster_AmazonEKSServicePolicy, ] provisioner "local-exec" { command = "aws --region ${var.region} eks update-kubeconfig --name ${aws_eks_cluster.eks_cluster.name}" } provisioner "local-exec" { when = destroy command = "kubectl config unset current-context" } } profile = var.profile }
还有另一个是诸如 EKS 集群这样的资源:
resource "aws_eks_cluster" "eks_cluster" { name = var.cluster_name role_arn = aws_iam_role.cluster_role.arn version = var.k8s_version vpc_config { security_group_ids = [aws_security_group.cluster_sg.id] subnet_ids = flatten([aws_subnet.subnet.*.id]) } depends_on = [ aws_iam_role_policy_attachment.cluster_AmazonEKSClusterPolicy, aws_iam_role_policy_attachment.cluster_AmazonEKSServicePolicy, ] provisioner "local-exec" { command = "aws --region ${var.region} eks update-kubeconfig --name ${aws_eks_cluster.eks_cluster.name}" } provisioner "local-exec" { when = destroy command = "kubectl config unset current-context" } }
每次运行 Terraform apply
命令时,它都会遍历这个文件,确定要创建哪些资源,调用哪些底层 AWS 服务来创建它们,以及他们应该使用哪组配置进行配置。这为编排诸如 Kubeflow 之类的复杂安装提供了一种清晰的方式,这是一种版本化的、可扩展的模板语言。
现在我们已经成功地在本地或在云端的托管 Kubernetes 控制面板上安装了 Kubeflow,让我们看看平台上有哪些可用的工具。
Kubeflow 组件简介
现在我们已经在本地或云端安装了 Kubeflow,让我们再次看看 Kubeflow 仪表板(图 2.8):
图 2.8:Kubeflow 仪表板
让我们来看看这个工具包提供了什么。首先,注意到在上面的面板中,我们有一个下拉菜单,其中指定了名称为anonymous
– 这是前面提到的 Kubernetes 的namespace
。虽然我们的默认值是anonymous
,但我们可以在我们的 Kubeflow 实例上创建多个命名空间,以容纳不同的用户或项目。这可以在登录时完成,我们在那里设置一个个人资料(图 2.9):
图 2.9:Kubeflow 登录页面
或者,与 Kubernetes 中的其他操作一样,我们可以使用 YAML 文件应用一个命名空间:
apiVersion: kubeflow.org/v1beta1 kind: Profile metadata: name: profileName spec: owner: kind: User name: userid@email.com
使用kubectl
命令:
kubectl create -f profile.yaml
一旦我们有了命名空间,我们可以做些什么呢?让我们看看可用的工具。
@kfp.dsl.component def my_component(my_param): ... return kfp.dsl.ContainerOp( name='My component name', image='gcr.io/path/to/container/image' ) or a function written in Python itself: @kfp.dsl.python_component( name='My awesome component', description='Come and play', ) def my_python_func(a: str, b: str) -> str:
对于纯 Python 函数,我们可以使用编译器将其转换为一个操作:
my_op = compiler.build_python_component( component_func=my_python_func, staging_gcs_path=OUTPUT_DIR, target_image=TARGET_IMAGE)
然后我们使用 dsl.pipeline
装饰器将此操作添加到流水线中:
@kfp.dsl.pipeline( name='My pipeline', description='My machine learning pipeline' ) def my_pipeline(param_1: PipelineParam, param_2: PipelineParam): my_step = my_op(a='a', b='b')
我们使用以下代码进行编译:
kfp.compiler.Compiler().compile(my_pipeline, 'my-pipeline.zip')
运行此代码:
client = kfp.Client() my_experiment = client.create_experiment(name='demo') my_run = client.run_pipeline(my_experiment.id, 'my-pipeline', 'my-pipeline.zip')
我们还可以将此 ZIP 文件上传到流水线 UI,在那里 Kubeflow 可以使用编译生成的 YAML 实例化作业。
现在你已经看到了生成单个流水线结果的过程,我们下一个问题是如何生成这样一个流水线的最佳参数。正如你将在第三章,深度神经网络的构建模块中看到的那样,神经网络模型通常具有多个配置,称为超参数,它们管理着它们的体系结构(例如层数、层大小和连接性)和训练范式(例如学习率和优化器算法)。Kubeflow 具有用于优化此类参数网格的内置实用程序,称为Katib。
使用 Kubeflow Katib 优化模型超参数
Katib 是一个框架,用于使用不同的输入运行同一作业的多个实例,例如神经架构搜索(用于确定神经网络中正确的层数和大小)和超参数搜索(例如为算法找到正确的学习率)。与我们见过的其他 Kustomize 模板一样,TensorFlow 作业指定了一个通用的 TensorFlow 作业,并为参数留有占位符:
apiVersion: "kubeflow.org/v1alpha3" kind: Experiment metadata: namespace: kubeflow name: tfjob-example spec: parallelTrialCount: 3 maxTrialCount: 12 maxFailedTrialCount: 3 objective: type: maximize goal: 0.99 objectiveMetricName: accuracy_1 algorithm: algorithmName: random metricsCollectorSpec: source: fileSystemPath: path: /train kind: Directory collector: kind: TensorFlowEvent parameters: - name: --learning_rate parameterType: double feasibleSpace: min: "0.01" max: "0.05" - name: --batch_size parameterType: int feasibleSpace: min: "100" max: "200" trialTemplate: goTemplate: rawTemplate: |- apiVersion: "kubeflow.org/v1" kind: TFJob metadata: name: {{.Trial}} namespace: {{.NameSpace}} spec: tfReplicaSpecs: Worker: replicas: 1 restartPolicy: OnFailure template: spec: containers: - name: tensorflow image: gcr.io/kubeflow-ci/tf-mnist-with- summaries:1.0 imagePullPolicy: Always command: - "python" - "/var/tf_mnist/mnist_with_summaries.py" - "--log_dir=/train/metrics" {{- with .HyperParameters}} {{- range .}} - "{{.Name}}={{.Value}}" {{- end}} {{- end}}
我们可以使用熟悉的 kubectl
语法来运行它:
kubectl apply -f https://raw.githubusercontent.com/kubeflow/katib/master/examples/v1alpha3/tfjob-example.yaml
Python 与 TensorFlow2 生成式 AI(一)(3)https://developer.aliyun.com/article/1512063