在 Alauda AI 中使用 LLM Compressor

本文档介绍如何结合使用 LLM Compressor 与 Alauda AI 平台来执行模型压缩工作流。LLM Compressor 的 Alauda AI 集成提供以下两个示例工作流:

notebook

支持的模型压缩工作流

在 Alauda AI 平台上,您可以使用 Workbench 功能,对存储在 S3、PVC 或 OCI registry 中的模型运行 LLM Compressor。以下工作流概述了压缩模型的典型步骤。

创建 Workbench

按照创建 Workbench 中的说明创建新的 Workbench 实例。创建 Workbench 时,请务必选择镜像 odh-workbench-jupyter-pytorch-llmcompressor-cuda-py312-ubi9,其中包含所需的 LLM Compressor 环境。目前仅支持在 JupyterLab 中进行模型压缩。

如果您的环境中没有此镜像,请参阅链接文章,了解如何同步该镜像并修补 WorkspaceKind 资源,使该镜像显示在 Workbench 创建选项中。

准备模型制品

将模型下载到 Workbench,或将其暂存到 Workbench 可访问的 PVC/S3 位置。压缩后,将输出上传到受支持的存储后端。请参阅 使用 Workbench 上传模型。 使用 Model Registry 将生成的 Model URI 注册为新的 Model Registry 版本。 本指南中的示例 notebook 使用 TinyLlama-1.1B-Chat-v1.0 模型。

data-free-compressor.ipynb
from llmcompressor.modifiers.quantization import QuantizationModifier

model_id = "./TinyLlama-1.1B-Chat-v1.0"
recipe = QuantizationModifier(targets="Linear", scheme="W4A16", ignore=["lm_head"])
  1. 要压缩的模型。如果要使用自己的模型,可以修改此行。2. 此 recipe 将量化除 lm_head 中的层之外的所有 Linear 层,因为该层通常对量化较为敏感。W4A16 方案 将权重压缩为 4-bit 整数,同时保留 16-bit 激活值。

(可选) 准备并上传数据集

NOTE

如果您计划使用 data-free compressor notebook,可以跳过此步骤。

要使用 calibration compressor notebook,必须准备并上传校准数据集。请按照 使用 Notebook 上传模型 中所述的相同流程准备数据集。示例校准 notebook 使用 ultrachat_200k 数据集。

calibration-compressor.ipynb
from datasets import load_dataset

dataset_id = "./ultrachat_200k"

num_calibration_samples = 512 if use_gpu else 4
max_sequence_length = 2048 if use_gpu else 16

ds = load_dataset(dataset_id, split="train_sft")
ds = ds.shuffle(seed=42).select(range(num_calibration_samples))

def preprocess(example): 
    text = tokenizer.apply_chat_template(
        example["messages"],
        tokenize=False,
    )
    return tokenizer(
        text,
        padding=False,
        max_length=max_sequence_length,
        truncation=True,
        add_special_tokens=False,
    )

ds = ds.map(preprocess, remove_columns=ds.column_names)
  1. 使用 Huggingface datasets API 创建校准数据集。如果要使用自己的数据集,可以 修改此行。2. 选择样本数量。建议从 512 个样本开始。增加 样本数量可以提高准确性。3. 加载数据集。4. 将数据集打乱,并仅获取 所需数量的样本。5. 预处理并 tokenization 为模型 使用的格式。

(可选) 将数据集上传到 S3 兼容的对象存储

如果要将数据集上传到 S3 兼容的对象存储,可以在 JupyterLab 中运行以下代码。Alauda AI 支持访问 S3 兼容的存储;在典型的产品部署中,存储实现为 Ceph 对象存储,因此可以使用标准 boto3 客户端。

import os
from boto3.s3.transfer import TransferConfig
import boto3

local_folder = "./ultrachat_200k"
bucket_name = "datasets"

config = TransferConfig(
    multipart_threshold=100*1024*1024,
    max_concurrency=10,
    multipart_chunksize=100*1024*1024,
    use_threads=True
)

for root, dirs, files in os.walk(local_folder):
    for filename in files:
        local_path = os.path.join(root, filename)
        relative_path = os.path.relpath(local_path, local_folder)
        s3_key = f"ultrachat_200k/{relative_path.replace(os.sep, '/')}"
        s3.upload_file(local_path, bucket_name, s3_key, Config=config)
        print(f"Uploaded {local_path} -> {s3_key}")
  1. 如果要使用自己的数据集,可以修改此行。2. 配置分段上传,分段大小为 100 MB,最大并发 线程数为 10。

(可选) 使用 S3 兼容对象存储中的数据集

如果要使用存储在 S3 兼容对象存储中的数据集,请先安装 s3fs 工具,然后按如下所示修改示例中的数据集加载部分。在 Alauda AI 环境中,此 S3 兼容存储通常由 Ceph 对象存储提供支持。

pip install s3fs -i https://pypi.tuna.tsinghua.edu.cn/simple
calibration-compressor.ipynb
import os
from datasets import load_dataset

os.environ["AWS_ACCESS_KEY_ID"] = "<access-key>"
os.environ["AWS_SECRET_ACCESS_KEY"] = "<secret-key>"

storage_options = {
  "key": "<access-key>",
  "secret": "<secret-key>",
  "client_kwargs": {
    "endpoint_url": "https://ceph-obj.example.com"
  }
}

ds = load_dataset(
      'parquet',
      data_files='s3://datasets/ultrachat_200k/data/train_sft-*.parquet', 
      storage_options=storage_options, 
      split="train"
)
  1. 设置环境变量(作为备用,某些底层组件会使用这些变量)。将 <access-key> 和 <secret-key> 替换为对象存储账户的凭证。
  2. 定义存储配置;必须为 S3 兼容对象存储服务显式指定 endpoint_url,例如 Ceph 对象存储端点。
  3. 如果数据集已拆分,这等同于示例中的 split="train_sft"。

在 JupyterLab 中下载模型和数据集

在 JupyterLab 终端中,使用 hf 命令行工具或获准使用的 对象存储客户端,将模型和数据集下载到 workspace 中。data-free compressor notebook 不需要数据集。

INFO

如果网络访问条件允许,建议使用 Hugging Face (hf) 命令行工具直接下载模型和数据集。与手动克隆存储库相比,这种方法通常更快速、更简单。

如果您处于网络受限的环境中,可以使用 Hugging Face 镜像来加速访问:

export HF_ENDPOINT=https://hf-mirror.com

您可以使用 hf 命令行工具直接下载模型和数据集。例如,要下载 TinyLlama 模型:

hf download TinyLlama/TinyLlama-1.1B-Chat-v1.0 --local-dir TinyLlama-1.1B-Chat-v1.0

对于校准数据集,可用类似方式下载:

hf download --repo-type dataset HuggingFaceH4/ultrachat_200k --local-dir ultrachat_200k

创建并运行压缩 Notebook

下载适合您使用场景的示例 notebook:如果使用数据集,请下载 calibration compressor notebook;否则,请下载 data-free compressor notebook。单击 JupyterLab 页面上的向上箭头按钮,上传已下载的 notebook 文件。

注册压缩后的模型

压缩完成后,使用使用 Workbench 上传模型 将压缩后的模型上传到 S3、PVC 或 OCI registry。 然后使用 Model Registry 将其 Model URI 注册为新的 Model Registry 版本。

model_dir = "./" + model_id.split("/")[-1] + "-W4A16"
model.save_pretrained(model_dir)
tokenizer.save_pretrained(model_dir);
  1. 保存模型和 tokenizer。如果要更改输出的名称,可以修改 此行。

部署压缩模型并将其用于推理

使用 LLM Compressor 创建的量化模型和稀疏模型会通过 compressed-tensors 库(Safetensors 的扩展)保存。 压缩格式与模型的量化或稀疏类型相匹配。vLLM 原生支持这些格式,因此可以使用 Alauda AI Inference Server,通过优化的部署 kernel 实现快速推理。 按照创建推理服务中的说明完成此步骤。