如何将 Jupyter Notebook 变成可部署的工件
机器学习工程团队面临的最大挑战之一,是如何高效地将模型研发阶段的大量工作投入生产。通常,模型的整个开发阶段都在 Jupyter Notebook 中完成,而 Jupyter Notebook 是一款专注于实验而非构建可部署工件的工具。
在本文中,您将了解如何应对这一挑战。我们将以一个在 Jupyter Notebook 中微调的LLama3 LLM模型为例,该模型带有Lora 适配器,然后使用KitOps和ModelKit将其转换为可部署的构件。该构件将成为部署在 Kubernetes 集群中的 Pod。
为什么 Jupyter Notebook 不能直接部署到生产环境中?
Jupyter Notebook是一个基于 Web 的交互式工具,可用于创建计算环境,生成包含代码和富文本元素的文档。Jupyter Notebook 是研发新型机器学习模型或新型微调方法的标准工具,因为它专注于:
- 即时观察结果。通过在指定单元格内交互式执行代码来实现。这有助于采用迭代式解决问题的方法和进行实验。
- 包含完整的计算流程,包括代码、解释和输出。这一特性有助于研究思想的可复制性和传播性。
- 与同事合作,促进协作努力并交流知识。
虽然 Jupyter Notebook 是数据探索和原型设计的正确工具,但它通常不适合直接部署在生产中,原因如下:
- 代码执行顺序并非线性,因为单元可以按任意顺序执行,这可能导致逻辑和隐藏状态(笔记本内发生变化的变量)的非线性流动。这使得理解代码的工作原理以及在生产环境中解决问题变得困难。
- 笔记本通常是单线程的,并非为处理高流量而设计。它在需要实时响应的应用程序中表现不佳,也无法在多个节点或集群之间高效运行。
- 笔记本可以执行任意代码,并且通常包含敏感信息、原始代码和数据,如果管理不善,可能会造成安全漏洞。
- 日志记录、监控以及与其他系统的集成在生产环境中很常见,而 Notebooks 并不是为这种类型的集成而构建的。
根据需求和团队技能,部署在 Jupyter Notebook 中开发的模型的方法有很多。本文将指导您如何使用 KitOps 和 ModelKit 部署 Kubernetes 初始化容器。
将您的模型投入生产需要经过哪些阶段?
使用 Jupyter Notebook,您可以开发和/或微调 AI/ML 模型,但模型需要经过特定阶段才能部署到生产环境。对于每个阶段,整个团队(数据科学家、ML 工程师、SRE)都需要不可变、安全且可共享的工件。
KitOps 和 ModelKits(一种符合 OCI 标准的打包格式)旨在满足这一需求。ModelKit 标准化了所有必要构件(包括数据集、代码、配置和模型)的打包方式,使开发过程更简单、更易于协作。
ML 模型的开发过程分为以下几个阶段:
- 未调优:在此阶段,数据集的设计将用于模型调优和模型验证。在此阶段,ModelKit 仅包含数据集和基础模型;例如,LLama3 指示量化 4。
- 已调优:在此阶段,模型已完成训练阶段。ModelKit 将包含模型、训练和验证数据集、包含微调代码的 Jupyter Notebook,以及用于特定用例的其他资源,例如用于 LLM 微调的 Lora 适配器。
- 挑战者:该模型应准备好取代当前的冠军模型。ModelKit 将包含所有应与该模型一起部署到生产环境中的代码库和数据集。
- 冠军:该模型已投入生产。这与挑战者标签的模型套件相同,但更新了标签,以显示其已投入生产。
接下来,您将看到使用 Kitops 实现这些阶段和创建不可变工件的逐步过程。
第 1 阶段:创建未调优的 ModelKit
首先,创建一个名为 llama3-finetune 的项目文件夹。在此文件夹中,创建两个子文件夹:一个用于存放数据集,另一个用于存放笔记本。如果您尚未安装 Kit CLI,请按照本指南进行安装。
打开你的shell并下载LLama3 80亿个参数,这些参数将从ModelKit进行微调:
kit login ghcr.io
kit unpack ghcr.io/jozu-ai/llama3:8B-instruct-q4_0
您的文件夹中会创建另一个文件:Kitfile。这是您的 ModelKit 的清单以及一组文件或目录,其中包括适配器、Jupyter Notebook 和数据集。
接下来,您已准备好开始 MLOps 流水线的第一步:创建训练数据集。如果您的目标是针对聊天用例微调像 LLama3 这样的开源大型语言模型,那么HuggingFace ultrachat_200K是一个广泛使用的数据集。
安装数据集包并将数据集下载到名为 finetune.ipynb 的新 Jupyter Notebook 中:
#install necessary packages:
!pip install datasets
#Download the dataset:
from datasets import load_dataset
ds = load_dataset("HuggingFaceH4/ultrachat_200k")
从此数据集开始,开发代码以适应您的特定用例。
在本用例中,数据集将使用聊天模板进行转换;首先,您需要安装 transforms 包:
#install necessary packages:
!pip install transformers
在 Jupyter Notebook 的下一个单元格中,使用apply_chat_template
为聊天用例创建训练和测试数据集:
import os
from transformers import AutoTokenizer
model_id = 'AgentPublic/llama3-instruct-8b'
train_dataset = ds['train_gen']
test_dataset = ds['test_gen']
tokenizer = AutoTokenizer.from_pretrained(model_id)
def format_chat_template(row):
chat = tokenizer.apply_chat_template(row["messages"], tokenize=False)
return chat
os.makedirs('../dataset', exist_ok=True)
with open('../dataset/train.txt', 'a', encoding='utf-8') as f_train:
for d in train_dataset:
f_train.write(format_chat_template(d))
with open('../dataset/test.txt', 'a', encoding='utf-8') as f_test:
for d in test_text:
f_test.write(format_chat_template(d))
数据集(训练集和测试集)保存在./dataset
文件夹中。
你的项目结构现在大致如下:
- llama3-finetune
|-- dataset
|-- train.txt
|-- test.txt
|-- notebooks
|-- finetune.ipynb
|-- kitfile
|-- llama3-8B-instruct-q4_0.gguf
此时,您需要更改 kitfile 以打包以下阶段所需的所有内容:
manifestVersion: "1.0"
package:
name: llama3 fine-tuned
version: 3.0.0
authors: [Jozu AI]
code:
- description: Jupyter notebook with dataset creation
path: ./notebooks
model:
name: llama3-8B-instruct-q4_0
path: ghcr.io/jozu-ai/llama3:8B-instruct-q4_0
description: Llama 3 8B instruct model
license: Apache 2.0
datasets:
- description: training set from ultrachat_200k
name: training_set
path: ./dataset/train.txt
- description: test set from ultrachat_200k
name: test_set
path: ./dataset/test.txt
现在可以将 Kitfile 推送到你的 Git 仓库,并可以使用untuned,
与 ModelKit 相同的标签标记此提交。在终端中输入:
kit pack /llama2_finetuning -t registry.gitlab.com/internal-llm/llama3-ultrachat-200k:untuned
kit push registry.gitlab.com/internal-llm/llama3-ultrachat-200k:untuned
第 2 步:微调模型
第二阶段是在 Jupyter Notebook 中微调模型,并编写执行此操作的代码。对于法学硕士 (LLM),一种可能的解决方案是使用llama.ccp微调 lora 适配器,如下所示:
# finetune LORA adapter
./bin/finetune \\
--model-base open-llama-3b-v2-q8_0.gguf \\
--checkpoint-in chk-lora-open-llama-3b-v2-q8_0-ultrachat-200k-LATEST.gguf \\
--checkpoint-out chk-lora-open-llama-3b-v2-q8_0-ultrachat-200k-ITERATION.gguf \\
--lora-out lora-open-llama-3b-v2-q8_0-ultrachat-200k-ITERATION.bin \\
--train-data "./dataset/train.txt" \\
--save-every 10 \\
--threads 6 --adam-iter 30 --batch 4 --ctx 64 \\
--use-checkpointing
在 llama.cpp 仓库中,您可以找到构建适合您架构的所有信息
。 微调完成后,您可以将 lora-adapters 部分添加到您的 Kitfile 中。这样,经过微调的 lora-adapter 将会打包到您的工件中。
manifestVersion: "1.0"
package:
name: llama3 fine-tuned
version: 3.0.0
authors: [Jozu AI]
code:
- description: Jupyter notebook with dataset creation
path: ./notebooks
model:
name: llama3-8B-instruct-q4_0
path: ghcr.io/jozu-ai/llama3:8B-instruct-q4_0
description: Llama 3 8B instruct model
license: Apache 2.0
parts:
- path: ./lora-open-llama-3b-v2-q8_0-ultrachat-200K-LATEST.bin
type: lora-adapter
datasets:
- description: training set from ultrachat_200k
name: training_set
path: ./data/train.txt
- description: test set from ultrachat_200k
name: test_set
path: ./data/test.txt
您可以将新版本的 Kitfile 推送到您的 Git 仓库,同时tuned
可以打包并推送该阶段的 KitModel。在终端中输入:
kit pack /llama2_finetuning -t registry.gitlab.com/internal-llm/llama3-ultrachat-200k:tuned
kit push registry.gitlab.com/internal-llm/llama3-ultrachat-200k:tuned
您可以多次运行微调阶段,更改训练参数或微调策略,或两者兼而有之。每次微调运行后,您都可以标记(即使用版本)一个新的 ModelKit,这样,您便拥有了所有微调尝试的记录。
第三阶段:创造挑战者
当对您的用例最重要的指标(例如准确率、精确率、召回率、F1 分数或平均绝对误差)超过您设置的阈值时,您的微调模型就准备好挑战冠军模型了;您可以将 ModelKit 标记为挑战者。在您的终端中,使用以下命令执行此操作:
kit pack /llama2_finetuning -t registry.gitlab.com/internal-llm/llama3-ultrachat-200k:challenger
kit push registry.gitlab.com/internal-llm/llama3-ultrachat-200k:challenger
请注意,在此阶段,ModelKit 包含微调所需的模型、数据集和代码。这样,任何人都可以完全重现微调阶段,挑战者也可以。
现在,挑战者模型可以部署到生产环境中进行 A/B 测试,并准备好挑战冠军模型。如果挑战者模型表现更佳,它就会成为冠军模型。现在,您可以将新版本的模型部署到生产环境中了。
第四阶段:部署新冠军
在此阶段,您可以重新标记相同的挑战者 ModelKit,其中包含模型(加上 lora 适配器)、代码和数据集,并使用新标签:champion。
对于部署到生产环境,例如通过 init 容器部署到 Kubernetes,您可以使用带有套件 CLI 的映像,并仅将模型解压到 pod 的共享卷中:
kit unpack registry.gitlab.com/internal-llm/llama3-ultrachat-200k:champion --model -d /path/to/shared/volume
现在,新的冠军已部署到生产中,并且从 Jupyter Notebook 到生产中模型的部署,MLOps 管道的每一步都已完成。
得益于KitOps和 ModelKit,模型的开发、微调和部署过程完全可复现。创建的每个工件都是不可变的,可在团队成员之间共享,安全可靠,并存储在您首选的容器镜像仓库或Jozu Hub等专用镜像仓库中。
文章来源:https://dev.to/kitops/how-to-turn-a-jupyter-notebook-into-a-deployable-artifact-2jdl