• Русский
  • Тонкая настройка LLM с использованием Workbench

    Введение

    Тонкая настройка и обучение моделей часто требуют адаптации к различным структурам моделей, аппаратным устройствам и соответствующим методам параллельного обучения. Alauda AI Workbench предоставляет комплексный подход — от разработки модели до подачи, управления задачами обучения и отслеживания экспериментов, помогая инженерам по моделям и алгоритмам быстро адаптироваться и завершить весь процесс тонкой настройки и обучения модели.

    В данном решении приведён пример тонкой настройки модели Qwen3-0.6B с использованием LLaMA-Factory.

    Alauda AI Workbench создаёт контейнерную среду Notebook/VSCode (CodeServer) для разработки и отладки в пространстве имён пользователя. В пространстве имён можно создавать несколько экземпляров Notebook/VSCode для сохранения окружений разных пользователей и задач разработки. Ноутбуки могут запрашивать только CPU-ресурсы для разработки и подачи задач в кластер, используя GPU-ресурсы кластера для выполнения задач. Также можно запрашивать GPU-ресурсы для Notebook, что позволяет выполнять задачи, такие как обучение и тонкая настройка, непосредственно в Notebook, независимо от того, требует ли модель распределённого обучения.

    Кроме того, вы можете использовать встроенный в платформу MLFlow для записи различных метрик каждой сессии тонкой настройки модели, что облегчает сравнение нескольких экспериментов и выбор итоговой модели.

    Для подачи задач в кластер из Notebook мы используем VolcanoJob — Kubernetes-native менеджер ресурсов. Планировщик Volcano поддерживает очереди, приоритеты и различные политики планирования, что способствует более эффективному планированию задач в кластере и повышению использования ресурсов.

    В этом решении используется LLaMA-Factory для запуска задач тонкой настройки и обучения. Однако для более масштабных сценариев тонкой настройки и обучения моделей, требующих параллельных методов, таких как Tensor Parallelism, Context Parallelism и Expert Parallelism для обучения больших моделей, может потребоваться использовать другие инструменты, создавать собственные runtime-образы для тонкой настройки и модифицировать скрипт запуска задачи для адаптации к различным инструментам и моделям. Для более подробного использования и настройки параметров LLaMA-Factory смотрите: https://llamafactory.readthedocs.io/en/latest/index.html

    Область применения

    • Решение применимо для Alauda AI версии 1.3 и выше.
    • Тонкая настройка и обучение моделей LLM. Для обучения других типов моделей (например, YOLOv5) потребуется использовать другие образы, скрипты запуска, наборы данных и т.д.
    • Решение применимо для сценариев с CPU x86/64 и GPU NVIDIA.
    • Для сценариев с NPU требуется построить подходящий runtime-образ на основе данного решения для совместимости.

    Подготовка

    • Сначала необходимо развернуть плагин "Alauda AI Workbench" для включения поддержки Workbench (или развернуть плагин Kubeflow Base для использования Notebook с Kubeflow).
    • Установить плагин MLFlow для отслеживания экспериментов.

    Шаги тонкой настройки LLM

    Создание экземпляра Notebook/VSCode

    Перейдите в Alauda AI - Workbench (или Advanced - Kubeflow - Notebook), затем создайте новый Notebook или используйте существующий. Рекомендуется, чтобы Notebook использовал только CPU-ресурсы. При подаче задачи в кластер из Notebook будут запрошены GPU-ресурсы кластера для повышения эффективности использования ресурсов.

    Подробные шаги создания экземпляра Notebook/VSCode смотрите в разделе Creating a Workbench.

    Подготовка модели

    Скачайте модель Qwen/Qwen3-0.6B с Huggingface или других сайтов с открытыми моделями. Затем загрузите модель в репозиторий моделей.

    Подробные шаги загрузки файлов модели в репозиторий смотрите в Upload Models Using Notebook.

    Подготовка места вывода модели

    Создайте пустую модель в репозитории моделей для хранения выходной модели. При настройке места вывода тонкой настройки укажите URL Git-репозитория модели.

    Подготовка набора данных

    Скачайте и загрузите пример набора данных identity в репозиторий наборов данных. Этот набор используется для тонкой настройки LLM, чтобы отвечать на вопросы пользователя, например, "Кто ты?"

    1. Сначала создайте пустой репозиторий набора данных в разделе "Datasets" - "Dataset Repository".
    2. Загрузите zip-файл в Notebook, распакуйте его, затем перейдите в каталог набора данных. Используйте git lfs для отправки набора данных в Git URL репозитория набора данных. Шаги аналогичны загрузке модели.
    3. После завершения отправки обновите страницу набора данных — в вкладке "File Management" вы увидите успешно загруженный файл.

    Примечание: Формат набора данных должен корректно распознаваться фреймворком тонкой настройки для использования в последующих задачах. Ниже приведены два распространённых формата наборов данных для тонкой настройки LLM:

    Формат набора данных Huggingface

    Вы можете использовать следующий код для проверки, корректно ли загружается формат каталога набора данных с помощью datasets:

    import datasets
    
    ds_infos = datasets.get_dataset_infos(<dataset directory>)
    ds = datasets.load_dataset(<dataset directory>)
    print(ds_infos)
    print(ds)

    Формат LLaMA-Factory

    Если вы используете инструмент LLaMA-Factory из примеров для обучения, формат набора данных должен соответствовать формату LLaMA-Factory. Справка: data_preparation

    Подготовка runtime-образа

    Используйте следующий Containerfile для сборки runtime-образа для обучения или используйте предсобранный образ: alaudadockerhub/fine_tune_with_llamafactory:v0.1.1. Если вы хотите использовать другой фреймворк обучения, например YOLOv5, возможно, потребуется кастомизировать образ и установить необходимые зависимости.

    После сборки образа загрузите его в реестр образов кластера платформы Alauda AI и настройте в последующих задачах.

    Примечание: В образе должна быть доступна команда git lfs для скачивания и загрузки файлов модели и набора данных.

    Containerfile
    ARG LLAMA_FACTORY_VERSION="v0.9.4"
    FROM python:3.13-trixie
    
    RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources && \
    apt-get update && \
    export DEBIAN_FRONTEND=noninteractive && \
    apt-get install -yq --no-install-recommends git git-lfs unzip curl ffmpeg default-libmysqlclient-dev build-essential pkg-config && \
    apt clean && rm -rf /var/lib/apt/lists/*
    
    RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -U pip setuptools && \
    cd /opt && \
    git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git && \
    cd LLaMA-Factory && git checkout ${LLAMA_FACTORY_VERSION} && \
    pip install --no-cache-dir -e ".[torch,metrics,deepspeed,awq,modelscope]" -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple \
    "transformers>=4.51.1,<5" \
    "tokenizers>=0.21.1" \
    "sqlalchemy~=2.0.30" \
    "pymysql~=1.1.1" \
    "loguru~=0.7.2" \
    "mysqlclient~=2.2.7" \
    "mlflow>=3.1"
    WORKDIR /opt

    Создание задачи VolcanoJob для тонкой настройки

    В Notebook создайте YAML-файл для подачи задачи. Пример приведён ниже:

    VolcanoJob YAML файл
    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
      generateName: vcjob-sft-qwen3-
    spec:
      minAvailable: 1
      schedulerName: volcano
      maxRetry: 1
      queue: default
      volumes:
        # PVC рабочего пространства, где выполняется задача (временный PVC)
        - mountPath: "/mnt/workspace"
          volumeClaim:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "sc-topolvm"
            resources:
              requests:
                storage: 5Gi
      tasks:
        - name: "train"
          # Количество параллельных реплик. Для распределённых задач обучения можно указать replicas > 2
          replicas: 1
          template:
            metadata:
              name: train
            spec:
              restartPolicy: Never
              securityContext:
                runAsNonRoot: true
                runAsUser: 65534
                runAsGroup: 65534
                fsGroup: 65534
              # Монтирование shm-устройства для предоставления разделяемой памяти, необходимой для коммуникации между несколькими GPU.
              volumes:
                - emptyDir:
                    medium: Memory
                    # Здесь можно настроить размер используемой разделяемой памяти
                    sizeLimit: 2Gi
                  name: dshm
                # PVC для хранения моделей и наборов данных.
                # В распределённых задачах обучения (с >= 2 репликами) убедитесь, что используете подходящий тип хранилища для кэширования больших моделей:
                # 1. Сетевое хранилище, например NFS или Ceph: просто монтируйте сетевое хранилище. Учтите, что несколько контейнеров могут одновременно обращаться к этому хранилищу, что приводит к высокой нагрузке. Кроме того, чтение больших файлов модели может быть медленнее, чем локальное чтение (в зависимости от производительности сетевого хранилища).
                # 2. Локальное хранилище, например topolvm или local-storage: используйте `kserve local model cache` для предварительного кэширования модели на каждом узле перед монтированием PVC. Задачи обучения не могут кэшировать каждый локальный PVC.
                - name: models-cache
                  persistentVolumeClaim:
                    claimName: wy-model-cache
              initContainers:
                - name: prepare
                  image: alaudadockerhub/fine_tune_with_llamafactory:v0.1.1
                  imagePullPolicy: IfNotPresent
                  env:
                  # Измените BASE_MODEL_URL на адрес базовой модели, DATASET_URL на адрес набора данных
                  - name: BASE_MODEL_URL
                    value: "https://<your-model-registry-git-address>/mlops-demo-ai-test/amlmodels/qwen3-0.6b"
                  - name: DATASET_URL
                    value: "https://<your-model-registry-git-address>/mlops-demo-ai-test/amldatasets/identity-alauda"
                  - name: GIT_USER
                    valueFrom:
                      secretKeyRef:
                        name: aml-image-builder-secret
                        key: MODEL_REPO_GIT_USER
                  - name: GIT_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: aml-image-builder-secret
                        key: MODEL_REPO_GIT_TOKEN
                  resources:
                    requests:
                      cpu: 100m
                      memory: 128Mi
                    limits:
                      cpu: 2
                      memory: 4Gi
                  securityContext:
                    allowPrivilegeEscalation: false
                    capabilities:
                      drop:
                        - ALL
                    runAsNonRoot: true
                    seccompProfile:
                      type: RuntimeDefault
                  volumeMounts:
                    - name: models-cache
                      mountPath: /mnt/models
                  command:
                  - /bin/bash
                  - -c
                  - |
                    set -ex
                    cd /mnt/models
                    BASE_MODEL_NAME=$(basename ${BASE_MODEL_URL})
                    # Скачиваем базовую модель
                    gitauth="${GIT_USER}:${GIT_TOKEN}"
                    BASE_MODEL_URL_NO_HTTPS="${BASE_MODEL_URL//https:\/\/}"
                    if [ -d ${BASE_MODEL_NAME} ]; then
                        echo "${BASE_MODEL_NAME} dir already exists, skip downloading"
                    else
                        GIT_LFS_SKIP_SMUDGE=1 git -c http.sslVerify=false -c lfs.activitytimeout=36000 clone "https://${gitauth}@${BASE_MODEL_URL_NO_HTTPS}"
                        (cd ${BASE_MODEL_NAME} && git -c http.sslVerify=false -c lfs.activitytimeout=36000 lfs pull)
                    fi
                    # Скачиваем набор данных
                    DATASET_NAME=$(basename ${DATASET_URL})
                    DATASET_URL_NO_HTTPS="${DATASET_URL//https:\/\/}"
     
                    rm -rf ${DATASET_NAME}
                    rm -rf data
                     
                    if [ -d ${DATASET_NAME} ]; then
                        echo "dataset ${DATASET_NAME} already exists skipping download"
                    else
                        git -c http.sslVerify=false -c lfs.activitytimeout=36000 clone "https://${gitauth}@${DATASET_URL_NO_HTTPS}"
                    fi
                    echo "listing files under /mnt/models ..."
                    ls /mnt/models
                    echo "listing model files ..."
                    ls ${BASE_MODEL_NAME}
                    echo "listing dataset files ..."
                    ls ${DATASET_NAME}
              containers:
                # Образ runtime-среды. Можно собрать аналогичный образ, используя src/llm/Containerfile. Обычно включает cuda, transformers, pytorch, datasets, evaluate и git lfs.
                - name: train
                  image: alaudadockerhub/fine_tune_with_llamafactory:v0.1.1
                  imagePullPolicy: IfNotPresent
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
                    - name: models-cache
                      mountPath: /mnt/models
                  env:
                    # Измените BASE_MODEL_URL на адрес базовой модели, DATASET_URL на адрес набора данных, OUTPUT_MODEL_URL на адрес выходной модели
                    - name: BASE_MODEL_URL
                      value: "https://<your-model-registry-git-address>/mlops-demo-ai-test/amlmodels/qwen3-0.6b"
                    - name: DATASET_URL
                      value: "https://<your-model-registry-git-address>/mlops-demo-ai-test/amldatasets/identity-alauda"
                    - name: OUTPUT_MODEL_URL
                      value: "https://<your-model-registry-git-address>/mlops-demo-ai-test/amlmodels/wy-sft-output"
                    # Каталог кэша, используемый библиотеками huggingface, такими как datasets, transformers и др.
                    - name: HF_HOME
                      value: /mnt/workspace/hf_cache
                    - name: DO_MERGE
                      value: "true"
                    - name: GIT_USER
                      valueFrom:
                        secretKeyRef:
                          name: aml-image-builder-secret
                          key: MODEL_REPO_GIT_USER
                    - name: GIT_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: aml-image-builder-secret
                          key: MODEL_REPO_GIT_TOKEN
                    # Измените MLFLOW_TRACKING_URI на фактический endpoint сервиса mlflow
                    - name: MLFLOW_TRACKING_URI
                      value: "http://mlflow-tracking-server.kubeflow:5000"
                    # Установите MLFLOW_EXPERIMENT_NAME в ваше пространство имён или имя эксперимента
                    - name: MLFLOW_EXPERIMENT_NAME
                      value: mlops-demo-ai-test
                  command:
                  - bash
                  - -c
                  - |
                    set -ex
                    echo "job workers list: ${VC_WORKER_HOSTS}"
                    if [ "${VC_WORKER_HOSTS}" != "" ]; then
                        export N_RANKS=$(echo "${VC_WORKER_HOSTS}" |awk -F',' '{print NF}')
                        export RANK=$VC_TASK_INDEX
                        export MASTER_HOST=$(echo "${VC_WORKER_HOSTS}" |awk -F',' '{print $1}')
                        export RANK=$RANK
                        export WORLD_SIZE=$N_RANKS
                        export NNODES=$N_RANKS
                        export NODE_RANK=$RANK
                        export MASTER_ADDR=${MASTER_HOST}
                        export MASTER_PORT="8888"
                    else
                        export N_RANKS=1
                        export RANK=0
                        export NNODES=1
                        export MASTER_HOST=""
                    fi
     
                    cd /mnt/workspace
                    BASE_MODEL_NAME=$(basename ${BASE_MODEL_URL})
                    DATASET_NAME=$(basename ${DATASET_URL})
     
                    cat >lf-sft.yaml <<EOL
                    model_name_or_path: /mnt/models/${BASE_MODEL_NAME}
       
                    stage: sft
                    do_train: true
                    finetuning_type: lora
                    lora_target: all
                    lora_rank: 8
                    lora_alpha: 16
                    lora_dropout: 0.1
       
                    dataset: identity_alauda
                    dataset_dir: /mnt/models/${DATASET_NAME}
                    template: qwen
                    cutoff_len: 1024
                    max_samples: 1000
                    overwrite_cache: true
                    preprocessing_num_workers: 8
       
                    output_dir: output_models
                    logging_steps: 10
                    save_steps: 500
                    plot_loss: true
                    overwrite_output_dir: true
       
                    # глобальный размер батча: 8
                    per_device_train_batch_size: 2
                    gradient_accumulation_steps: 2
                    learning_rate: 2.0e-4
                    num_train_epochs: 4.0
                    bf16: false
                    fp16: true
                    ddp_timeout: 180000000
       
                    val_size: 0.1
                    per_device_eval_batch_size: 1
                    eval_strategy: steps
                    eval_steps: 500
                    report_to: mlflow
                    EOL
     
                    # Запуск обучения
                    if [ ${NNODES} -gt 1 ]; then
                        echo "deepspeed: ds-z3-config.json" >> lf-sft.yaml
                        FORCE_TORCHRUN=1 llamafactory-cli train lf-sft.yaml
                    else
                        unset NNODES
                        unset NODE_RANK
                        unset MASTER_ADDR
                        unset MASTER_PORT
                        llamafactory-cli train lf-sft.yaml
                    fi
    
                    if [ "${DO_MERGE}" == "true" ]; then
                      # Слияние адаптеров LoRA
                      cat >lf-merge-config.yaml <<EOL
                    model_name_or_path: /mnt/models/${BASE_MODEL_NAME}
                    adapter_name_or_path: output_models
                    template: qwen
                    finetuning_type: lora
        
                    ### экспорт
                    export_dir: output_models_merged
                    export_size: 4
                    export_device: cpu
                    export_legacy_format: false
                    EOL
                         
                      llamafactory-cli export lf-merge-config.yaml
                    else
                      # перемещение выходного адаптера для отправки
                      mv output_models output_models_merged
                    fi
                    # отправка объединённой модели в репозиторий моделей
                    gitauth="${GIT_USER}:${GIT_TOKEN}"
                    cd /mnt/workspace/output_models_merged
                    touch README.md
                    OUTPUT_MODEL_NO_HTTPS="${OUTPUT_MODEL_URL//https:\/\/}"
                    PUSH_URL="https://${gitauth}@${OUTPUT_MODEL_NO_HTTPS}"
                    push_branch=$(date +'%Y%m%d-%H%M%S')
     
                    git init
                    git checkout -b sft-${push_branch}
                    git lfs track *.safetensors
                    git add .
                    git -c user.name='AMLSystemUser' -c user.email='aml_admin@cpaas.io' commit -am "fine tune push auto commit"
                    git -c http.sslVerify=false -c lfs.activitytimeout=36000 push -u ${PUSH_URL} sft-${push_branch}
                  resources:
                    # Убедитесь, что ресурсов достаточно для выполнения тонкой настройки. Если требуется GPU, запросите соответствующие GPU/vGPU ресурсы.
                    requests:
                      cpu: "1"
                      memory: "2Gi"
                    limits:
                      cpu: "8"
                      memory: "16Gi"
                      nvidia.com/gpu: 1
                  securityContext:
                    allowPrivilegeEscalation: false
                    capabilities:
                      drop:
                        - ALL
                    runAsNonRoot: true
                    seccompProfile:
                      type: RuntimeDefault

    В приведённом YAML-файле перед подачей задачи измените следующие настройки.

    1. Образ: содержит зависимости, необходимые для выполнения задачи.
    2. Переменные окружения: адреса исходной модели, набора данных и выходной модели для задачи:
    • BASE_MODEL_URL: измените на Git URL подготовленной модели.
    • DATASET_URL: измените на Git URL подготовленного набора данных identity-alauda.
    • OUTPUT_MODEL_URL: создайте пустую модель в репозитории моделей для хранения выходной модели и укажите Git URL этой модели.
    1. Требуемые ресурсы для задачи, включая:
    • PVC кэша модели (опционально): PVC для хранения базовой модели (при запуске задач предварительного обучения можно пропустить скачивание базовой модели) и набора данных. Необходимо вручную создать и указать PVC в YAML-файле выше. Используйте этот "model cache PVC" для ускорения нескольких экспериментов тонкой настройки на разных моделях.
    • PVC рабочего пространства (обязательно): PVC и рабочий каталог, где выполняется задача. Здесь будут храниться контрольные точки и выходные файлы модели. В приведённом примере используется временный PVC, который удаляется после завершения задачи, так как выходная модель уже загружена в репозиторий моделей.
    • Разделяемая память: для многогруппового/распределённого обучения рекомендуется выделять не менее 4 Gi разделяемой памяти.
    • CPU, память и GPU ресурсы, необходимые для задачи (на основе плагина GPU-устройств, развернутого в кластере).
    1. Скрипт выполнения задачи:
    2. Пример скрипта включает кэширование модели из репозитория в PVC, кэширование обучающего набора данных в PVC и отправку модели в новый репозиторий после тонкой настройки. Вы можете кастомизировать скрипт под свои задачи.
    3. Пример использует LLaMA-Factory для запуска задачи тонкой настройки, который подходит для большинства сценариев обучения LLM.
    4. Гиперпараметры: в примере гиперпараметры определены непосредственно в скрипте запуска. Можно также использовать переменные окружения для чтения гиперпараметров, которые могут часто изменяться, что облегчает многократный запуск и настройку.

    Примечание по использованию PVC на основе NFS

    При использовании NFS в качестве PVC рабочего пространства или кэша модели необходимо выполнить следующие действия, чтобы обеспечить корректные права файловой системы на смонтированном NFS томе:

    • На всех узлах K8s, которые могут использовать NFS PVC, должен быть установлен пакет nfs-utils, например, yum install -y nfs-utils.

    • При создании класса хранилища NFS добавьте параметр mountPermissions: "0757", например:

      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: ai-nfs
        labels:
          project.cpaas.io/name: null
          project.cpaas.io/ALL_ALL: "true"
        annotations:
          cpaas.io/display-name: ""
          cpaas.io/access-mode: ReadWriteOnce,ReadWriteMany
          cpaas.io/features: ""
      provisioner: nfs.csi.k8s.io
      parameters:
        mountPermissions: "0757"
        server: 192.168.17.28
        share: /nfs_data/int/ai
      reclaimPolicy: Delete
      volumeBindingMode: Immediate
      mountOptions:
        - hard
        - nfsvers=4.1
      driverName: ""

    После выполнения вышеуказанных настроек откройте терминал в Notebook и выполните: kubectl create -f vcjob_sft.yaml для подачи VolcanoJob в кластер.

    Управление задачей

    В терминале Notebook:

    1. Выполните kubectl get vcjob для просмотра списка задач, затем kubectl get vcjob <имя задачи> для просмотра статуса задачи VolcanoJob.
    2. Выполните kubectl get pod для просмотра статуса pod, и kubectl logs <имя pod> для просмотра логов задачи. Для распределённых задач может быть несколько pod.
    3. Если pod не создаётся, выполните kubectl describe vcjob <имя задачи> или kubectl get podgroups для просмотра podgroup Volcano. Также можно проверить логи планировщика Volcano, чтобы определить, связана ли проблема с нехваткой ресурсов, невозможностью монтирования PVC или другими вопросами планирования.
    4. После успешного выполнения задачи тонко настроенная модель автоматически отправляется в репозиторий моделей. Обратите внимание, что задача автоматически создаёт ветку репозитория для отправки на основе времени. При использовании выходной модели обязательно выбирайте правильную версию.

    Для удаления задачи выполните kubectl delete vcjob <имя задачи>.

    Отслеживание экспериментов

    В приведённом примере задачи тонкой настройки мы используем LLaMA-Factory для запуска задачи и устанавливаем report_to: mlflow в конфигурации задачи. Это автоматически выводит метрики обучения на сервер mlflow. После запуска задачи вы можете найти записи отслеживания экспериментов в разделе Alauda AI - Advanced - MLFlow и сравнить несколько запусков. Например, можно сравнить потери (loss) нескольких экспериментов.

    Запуск сервиса вывода с использованием тонко настроенной модели

    После завершения задачи тонкой настройки модель автоматически отправляется в репозиторий моделей. Вы можете использовать тонко настроенную модель для запуска сервиса вывода и доступа к нему.

    Примечание: В приведённом примере используется метод тонкой настройки LoRA. Перед загрузкой модели адаптер LoRA был объединён с исходной моделью. Это позволяет напрямую публиковать выходную модель в сервис вывода. Запуск сервиса вывода с использованием базовой модели и адаптеров НЕ поддерживается в текущей версии.

    Шаги:

    1. Перейдите в Alauda AI - Model Repository, найдите тонко настроенную выходную модель, перейдите в Model Info - File Management - Edit Metadata, выберите "Task Type": "Text Classification" и "Framework": "Transformers".
    2. Нажмите кнопку Publish Inference API, затем выберите Custom Publishing.
    3. На странице публикации сервиса вывода выберите runtime вывода vLLM (выберите vLLM с версией CUDA, поддерживаемой GPU-узлами кластера), заполните настройки хранилища, ресурсов, GPU и нажмите Publish.
    4. Дождитесь полного запуска сервиса вывода, затем нажмите кнопку Experience в правом верхнем углу для начала общения с моделью. (Примечание: модели с конфигурацией chat_template имеют только возможности чата.)

    Запуск на GPU не-Nvidia

    При использовании среды с GPU не-Nvidia (например, NPU, Intel Gaudi, AMD и др.) вы можете следовать общим шагам ниже для тонкой настройки моделей, запуска задач обучения и их управления в AML Notebook.

    Примечание: Следующие шаги также применимы для предобучения LLM и традиционных ML-сценариев. Это общие шаги по адаптации решения поставщика для запуска на Alauda AI с использованием Notebook и VolcanoJob.

    Подготовка

    1. Предварительно: драйвер GPU поставщика и плагин устройства Kubernetes должны быть развернуты в кластере. Устройства должны быть доступны внутри pod, созданного Kubernetes. Примечание: необходимо знать имя ресурса GPU поставщика и общее количество устройств в кластере для удобства подачи задач. Например, для Huawei NPU можно запросить карту NPU с помощью: huawei.com/Ascend910:1.
    2. Получите документацию и материалы решения поставщика для тонкой настройки на GPU данного поставщика. Обычно это включает:
    3. Документацию и шаги решения. Это может быть выполнено на Kubernetes или в контейнере с помощью nerdctl run.
    4. Образ для запуска тонкой настройки. Например, поставщик предоставляет решение тонкой настройки с использованием LLaMA-Factory и соответствующий образ LLaMA-Factory (который может быть включён в образ).
    5. Модель для тонкой настройки. Обычно устройства поставщика поддерживают ряд моделей. Используйте поддерживаемые модели или модели из решения поставщика.
    6. Данные для обучения. Используйте пример данных из документации решения поставщика или создайте собственный набор данных в том же формате.
    7. Команда запуска задачи и параметры. Например, решение тонкой настройки на базе LLaMA-Factory использует команду llamafactory-cli для запуска задачи и настройки параметров, включая гиперпараметры задачи, в YAML-файле.

    Проверка оригинального решения поставщика (опционально)

    Для гарантии корректного выполнения решения поставщика и уменьшения последующих проблем с отладкой можно сначала полностью запустить решение согласно документации поставщика и убедиться, что оно работает корректно.

    Этот шаг можно пропустить. Однако при возникновении проблем с выполнением задачи позже можно вернуться к этому шагу для проверки исходного решения.

    Конвертация решения поставщика для запуска как Kubernetes Job/Deployment (опционально)

    Если решение поставщика уже работает как Kubernetes job/deployment/pod, этот шаг можно пропустить.

    Если решение поставщика использует метод запуска контейнера, например nerdctl run, можно сначала использовать простой Kubernetes job для проверки корректности работы решения в Kubernetes-среде с развернутым плагином устройства поставщика.

    Примечание: Этот шаг позволяет исключить проблемы с невозможностью планирования GPU-устройств поставщика в volcano job, поэтому его можно проверить отдельно.

    Пример:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: custom-gpu-ft-job
    spec:
      template:
        spec:
          containers:
          - name: train
            image: <Image used by the vendor to fine-tune training solutions>
            command: ["Task start command", "Parameter 1", "Parameter 2"]
          restartPolicy: Never
      # Примечание: для распределённых задач можно указать параллелизм, изменяя parallelism, completions.
      completions: 1
      parallelism: 1

    Модификация решения поставщика для запуска как volcano job

    Смотрите пример определения YAML ниже.

    VolcanoJob YAML файл
    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
      generateName: vcjob-sft-
    spec:
      minAvailable: 1
      schedulerName: volcano
      maxRetry: 1
      queue: default
      volumes:
        # PVC рабочего пространства, где выполняется задача (временный PVC)
        - mountPath: "/mnt/workspace"
          volumeClaim:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "sc-topolvm"
            resources:
              requests:
                storage: 5Gi
      tasks:
        - name: "train"
          # Количество параллельных реплик. Для распределённых задач обучения можно указать replicas >= 2
          replicas: 1
          template:
            metadata:
              name: train
            spec:
              restartPolicy: Never
              # Монтирование shm-устройства для предоставления разделяемой памяти, необходимой для коммуникации между несколькими GPU.
              volumes:
                - emptyDir:
                    medium: Memory
                    # Здесь можно настроить размер используемой разделяемой памяти
                    sizeLimit: 2Gi
                  name: dshm
                # PVC для хранения моделей и наборов данных.
                # В распределённых задачах обучения (с >= 2 репликами) убедитесь, что используете подходящий тип хранилища для кэширования больших моделей:
                # 1. Сетевое хранилище, например NFS или Ceph: просто монтируйте сетевое хранилище. Учтите, что несколько контейнеров могут одновременно обращаться к этому хранилищу, что приводит к высокой нагрузке. Кроме того, чтение больших файлов модели может быть медленнее, чем локальное чтение (в зависимости от производительности сетевого хранилища).
                # 2. Локальное хранилище, например topolvm или local-storage: используйте `kserve local model cache` для предварительного кэширования модели на каждом узле перед монтированием PVC. Задачи обучения не могут кэшировать каждый локальный PVC.
                - name: models-cache
                  persistentVolumeClaim:
                    claimName: sft-qwen3-volume
              containers:
                # Образ среды выполнения.
                - image: <Укажите образ, используемый решением поставщика, или кастомизируйте образ на месте>
                  imagePullPolicy: IfNotPresent
                  name: train
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
                    - name: models-cache
                      mountPath: /mnt/models
                  env:
                    - name: MLFLOW_TRACKING_URI
                      value: "http://mlflow-tracking-server.aml-system.svc.cluster.local:5000"
                    - name: MLFLOW_EXPERIMENT_NAME
                      value: kubeflow-admin-cpaas-io
                  command:
                  - bash
                  - -c
                  - |
                    set -ex
                    echo "job workers list: ${VC_WORKER_HOSTS}"
                    # добавьте команды запуска задачи ниже
                    # ...
                  resources:
                    # Убедитесь, что ресурсов достаточно для выполнения тонкой настройки. Если требуется GPU, запросите соответствующие GPU/vGPU ресурсы.
                    requests:
                      cpu: "1"
                      memory: "8Gi"
                    limits:
                      cpu: "8"
                      memory: "16Gi"
                      nvidia.com/gpualloc: "1"
                      nvidia.com/gpucores: "50"
                      nvidia.com/gpumem: "8192"

    Отслеживание экспериментов

    Некоторые фреймворки тонкой настройки/обучения автоматически записывают прогресс эксперимента в различные сервисы отслеживания экспериментов. Например, фреймворки LLaMA-Factory и Transformers могут настраиваться на запись прогресса в сервисы, такие как mlflow и wandb. В зависимости от вашей инфраструктуры можно настроить следующие переменные окружения:

    • MLFLOW_TRACKING_URI: URL сервера отслеживания mlflow.
    • MLFLOW_EXPERIMENT_NAME: имя эксперимента, обычно используется имя пространства имён. Это позволяет группировать задачи.

    Фреймворк также указывает место записи. Например, LLaMA-Factory требует указания report_to: mlflow в YAML-файле конфигурации параметров задачи.

    После запуска задачи обучения вы можете найти соответствующую задачу в интерфейсе Alauda AI - "Advanced" - MLFlow и просмотреть графики каждой записанной метрики в разделе "Metrics" или параметры конфигурации каждого запуска. Также можно сравнивать несколько экспериментов.

    Итог

    Используя среду разработки Alauda AI Notebook, вы можете быстро подавать задачи тонкой настройки и обучения в кластер с помощью YAML и командной строки, а также управлять статусом выполнения этих задач. Такой подход позволяет быстро разрабатывать и настраивать шаги тонкой настройки и обучения моделей, обеспечивая выполнение операций, таких как LLM SFT, согласование предпочтений, традиционное обучение моделей и сравнение нескольких экспериментов.