• Русский
  • Extend Inference Runtimes

    Introduction

    Этот документ пошагово объясняет, как добавить новые среды выполнения инференса для обслуживания как больших языковых моделей (LLM), так и других моделей, таких как «классификация изображений», «обнаружение объектов», «классификация текста» и т.д.

    Alauda AI поставляется с встроенным движком инференса "vLLM". С помощью «пользовательских сред выполнения инференса» вы можете добавить другие движки инференса, например, Seldon MLServer, Triton inference server и так далее.

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

    В этом разделе мы продемонстрируем расширение текущей AI платформы с помощью пользовательской среды выполнения сервиса инференса Xinference для развертывания LLM и предоставления «совместимого с OpenAI API» сервиса.

    Scenarios

    Рассмотрите возможность расширения сред выполнения сервиса инференса вашей AI платформы, если вы столкнулись с одной из следующих ситуаций:

    • Поддержка новых типов моделей: ваша модель не поддерживается по умолчанию текущей средой выполнения инференса vLLM.
    • Совместимость с другими типами GPU: вам необходимо выполнять инференс LLM на оборудовании с GPU, такими как AMD или Huawei Ascend.
    • Оптимизация производительности для конкретных сценариев: в некоторых сценариях инференса новая среда выполнения (например, Xinference) может обеспечить лучшую производительность или использование ресурсов по сравнению с существующими средами.
    • Пользовательская логика инференса: требуется внедрить пользовательскую логику инференса или зависимые библиотеки, которые сложно реализовать в существующих стандартных средах.

    Prerequisites

    Перед началом убедитесь, что выполнены следующие условия:

    1. Ваш кластер ACP развернут и работает нормально.
    2. Версия вашей AI платформы 1.3 или выше.
    3. У вас подготовлены необходимые образы среды выполнения инференса. Например, для среды Xinference образы могут выглядеть как xprobe/xinference:v1.2.2 (для GPU) или xprobe/xinference:v1.2.2-cpu (для CPU).
    4. У вас есть привилегии администратора кластера (необходимы для создания экземпляров CRD).

    Standard Workflow (Example: Xinference)

    Следуйте этим шагам для расширения платформы. В качестве базового примера используется Xinference, чтобы продемонстрировать стандартный процесс.

    Создание ресурсов среды выполнения инференса

    Необходимо создать соответствующие ресурсы среды выполнения инференса ClusterServingRuntime в зависимости от целевой аппаратной среды (GPU/CPU/NPU).

    1. Подготовьте YAML-конфигурацию среды выполнения:

      В зависимости от типа среды выполнения, которую вы хотите добавить (например, Xinference), и вашей целевой аппаратной среды подготовьте соответствующий YAML-файл конфигурации. Ниже приведены примеры для среды Xinference на разных аппаратных платформах:

    • Пример среды для GPU
      # Это пример YAML для среды Xinference на GPU
      apiVersion: serving.kserve.io/v1alpha1
      kind: ClusterServingRuntime
      metadata:
        name: aml-xinference-cuda-12.1 # Имя ресурса среды выполнения
        labels:
          cpaas.io/runtime-class: xinference # обязательная метка типа среды выполнения
          cpaas.io/accelerator-type: "nvidia"
          cpaas.io/cuda-version: "12.1"
        annotations:
          cpaas.io/display-name: xinference-cuda-12.1 # Отображаемое имя в UI
      spec:
        containers:
        - name: kserve-container
          image: xprobe/xinference:v1.2.2  # Замените на ваш реальный образ среды выполнения для GPU
          env:
          # Обязательный параметр для всех сред — путь к директории модели
          - name: MODEL_PATH
            value: /mnt/models/{{ index .Annotations "aml-model-repo" }}
          # Параметр MODEL_UID необязателен для других сред.
          - name: MODEL_UID 
            value: '{{ index .Annotations "aml-model-repo" }}'
          # Параметр MODEL_ENGINE обязателен для среды Xinference, в других средах может отсутствовать.
          - name: MODEL_ENGINE 
            value: "transformers"
          # Обязательный параметр для среды Xinference, укажите в соответствии с семейством вашей модели, например: "llama", "chatglm" и т.д.
          - name: MODEL_FAMILY 
            value: ""
          command:
          - bash
          - -c
          - |
              set +e
              if [ "${MODEL_PATH}" == "" ]; then
                  echo "Необходимо задать MODEL_PATH!"
                  exit 1
              fi
              if [ "${MODEL_ENGINE}" == "" ]; then
                  echo "Необходимо задать MODEL_ENGINE!"
                  exit 1
              fi
              if [ "${MODEL_UID}" == "" ]; then
                  echo "Необходимо задать MODEL_UID!"
                  exit 1
              fi
              if [ "${MODEL_FAMILY}" == "" ]; then
                  echo "Необходимо задать MODEL_FAMILY!"
                  exit 1
              fi
      
              xinference-local --host 0.0.0.0 --port 8080 &
              PID=$!
              while [ true ];
              do
                  curl http://127.0.0.1:8080/docs
                  if [ $? -eq 0 ]; then
                      break
                  else
                      echo "ожидание готовности сервера xinference-local..."
                      sleep 1
                  fi
              done
      
              set -e
              xinference launch --model_path ${MODEL_PATH} --model-engine ${MODEL_ENGINE} -u ${MODEL_UID} -n ${MODEL_FAMILY} -e http://127.0.0.1:8080 $@
              xinference list -e http://127.0.0.1:8080
              echo "модель успешно загружена, ожидание процесса сервера: ${PID}..."
              wait ${PID}
          # Добавьте эту строку, чтобы использовать $@ в скрипте:
          # см. https://unix.stackexchange.com/questions/144514/add-arguments-to-bash-c
          - bash
          resources:
            limits:
              cpu: 2
              memory: 6Gi
            requests:
              cpu: 2
              memory: 6Gi
          startupProbe:
            httpGet:
              path: /docs
              port: 8080
              scheme: HTTP
            failureThreshold: 60 
            periodSeconds: 10
            timeoutSeconds: 10
        supportedModelFormats:
          - name: transformers # Формат модели, поддерживаемый средой выполнения
            version: "1"
      
      • Совет: Обязательно замените значение поля image на путь к вашему реальному подготовленному образу среды выполнения. Вы также можете изменить поле annotations.cpaas.io/display-name для кастомизации отображаемого имени среды выполнения в UI AI платформы.
    1. Примените YAML-файл для создания ресурса:

      Выполните в терминале с правами администратора кластера команду:

      kubectl apply -f your-xinference-runtime.yaml
      TIP
      • Важный совет: Пожалуйста, ориентируйтесь на приведённые выше примеры и создавайте/конфигурируйте среду выполнения в соответствии с вашей реальной средой и требованиями инференса. Эти примеры приведены для справки. Вам нужно будет настроить параметры, такие как образ, лимиты ресурсов и запросы, чтобы среда выполнения была совместима с вашей моделью и аппаратной средой и работала эффективно.
      • Примечание: Вы сможете использовать эту пользовательскую среду выполнения на странице публикации сервиса инференса только после создания ресурса среды выполнения!

    Публикация сервиса инференса Xinference и выбор среды выполнения

    После успешного создания ресурса среды выполнения Xinference вы сможете выбрать и настроить её при публикации сервиса инференса LLM на AI платформе.

    1. Настройте фреймворк инференса для модели:

      Убедитесь, что на странице деталей модели в репозитории модели, которую вы собираетесь публиковать, выбран соответствующий фреймворк через функцию редактирования метаданных «File Management». Значение параметра фреймворка должно совпадать со значением из поля supportedModelFormats, указанного при создании среды выполнения инференса. Пожалуйста, убедитесь, что значение параметра фреймворка модели входит в список supportedModelFormats, заданный в среде выполнения.

    2. Перейдите на страницу публикации сервиса инференса:

      Войдите в AI платформу и перейдите в разделы «Inference Services» или «Model Deployment», затем нажмите «Publish Inference Service».

    3. Выберите среду выполнения Xinference:

      В мастере создания сервиса инференса найдите опцию «Runtime» или «Inference Framework». В выпадающем списке выберите среду Xinference, созданную на шаге 1 (например, «Xinference CPU Runtime» или «Xinference GPU Runtime (CUDA)»).

    4. Установите переменные окружения: Среда Xinference требует определённых переменных окружения для корректной работы. На странице конфигурации сервиса инференса найдите раздел «Environment Variables» или «More Settings» и добавьте следующую переменную окружения:

      • Описание параметра переменной окружения

        Имя параметраОписание
        MODEL_FAMILYОбязательно. Указывает семейство LLM модели, которую вы разворачиваете. Xinference использует этот параметр для идентификации и загрузки правильной логики инференса для модели. Например, если вы разворачиваете модель Llama 3, установите значение llama; если ChatGLM — chatglm. Пожалуйста, задайте это в соответствии с семейством вашей модели.
      • Пример:

        • Имя переменной: MODEL_FAMILY
        • Значение переменной: llama (если вы используете модель серии Llama, ознакомьтесь с документацией для подробностей. Также можно выполнить xinference registrations -t LLM для списка всех поддерживаемых семейств моделей.)

    Specific Runtime Examples

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

    MLServer

    Среда выполнения MLServer универсальна и может использоваться как на NVIDIA GPU, так и на CPU.

    kind: ClusterServingRuntime
    apiVersion: serving.kserve.io/v1alpha1
    metadata:
      annotations:
        cpaas.io/display-name: mlserver-cuda11.6-x86-arm
      creationTimestamp: 2026-01-05T07:02:33Z
      generation: 1
      labels:
        cpaas.io/accelerator-type: nvidia
        cpaas.io/cuda-version: "11.6"
        cpaas.io/runtime-class: mlserver
      name: aml-mlserver-cuda-11.6
    spec:
      containers:
        - command:
            - /bin/bash
            - -lc
            - |
              if [ "$MODEL_TYPE" = "text-to-image" ]; then
                MODEL_IMPL="mlserver_diffusers.StableDiffusionRuntime"
              else
                MODEL_IMPL="mlserver_huggingface.HuggingFaceRuntime"
              fi            
    
              MODEL_DIR="${MLSERVER_MODEL_URI}/${MLSERVER_MODEL_NAME}"
              # a. using git lfs storage initializer, model will be in /mnt/models/<model_name>
              # b. using hf storage initializer, model will be in /mnt/models
              if [ ! -d "${MODEL_DIR}" ]; then
                  MODEL_DIR="${MLSERVER_MODEL_URI}"
                  echo "[WARNING] Model directory ${MODEL_DIR}/${MLSERVER_MODEL_NAME} not found, using ${MODEL_DIR} instead"
              fi
    
              export MLSERVER_MODEL_IMPLEMENTATION=${MODEL_IMPL}
              export MLSERVER_MODEL_EXTRA="{\"task\":\"${MODEL_TYPE}\",\"pretrained_model\":\"${MODEL_DIR}\"}"            
    
              mlserver start $MLSERVER_MODEL_URI $@
            - bash
          env:
            - name: MLSERVER_MODEL_URI
              value: /mnt/models
            - name: MLSERVER_MODEL_NAME
              value: '{{ index .Annotations "aml-model-repo" }}'
            - name: MODEL_TYPE
              value: '{{ index .Annotations "aml-pipeline-tag" }}'
          image: alaudadockerhub/seldon-mlserver:1.6.0-cu116-v1.3.1
          name: kserve-container
          resources:
            limits:
              cpu: 2
              memory: 6Gi
            requests:
              cpu: 2
              memory: 6Gi
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            runAsNonRoot: true
            runAsUser: 1000
          startupProbe:
            failureThreshold: 60
            httpGet:
              path: /v2/models/{{ index .Annotations "aml-model-repo" }}/ready
              port: 8080
              scheme: HTTP
            periodSeconds: 10
            timeoutSeconds: 10
      labels:
        modelClass: mlserver_sklearn.SKLearnModel
      supportedModelFormats:
        - name: mlflow
          version: "1"
        - name: transformers
          version: "1"
    

    Triton Inference Server

    Среда выполнения Triton Inference Server предназначена для NVIDIA GPU и поддерживает несколько форматов моделей. Аналогично MLServer, сначала создайте ресурс ClusterServingRuntime, затем создайте сервис инференса.

    apiVersion: serving.kserve.io/v1alpha1
    kind: ClusterServingRuntime
    metadata:
      annotations:
        cpaas.io/display-name: triton-cuda12-x86
      labels:
        cpaas.io/accelerator-type: nvidia
        cpaas.io/cuda-version: "12.1"
        cpaas.io/runtime-class: triton
      name: aml-triton-cuda-12
    spec:
      containers:
        - command:
            - /bin/bash
            - -c
            - >
              tritonserver --log-verbose=1 --http-port=8080
              --model-repository=/mnt/models
          env:
            - name: OMP_NUM_THREADS
              value: "1"
            - name: MODEL_REPO
              value: '{{ index .Annotations "aml-model-repo" }}'
          image: alaudadockerhub/tritonserver:25.02-py3
          name: kserve-container
          resources:
            limits:
              cpu: 2
              memory: 6Gi
            requests:
              cpu: 2
              memory: 6Gi
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            privileged: false
            runAsNonRoot: true
            runAsUser: 1000
          startupProbe:
            failureThreshold: 60
            httpGet:
              path: /v2/models/{{ index .Annotations "aml-model-repo" }}/ready
              port: 8080
              scheme: HTTP
            periodSeconds: 10
            timeoutSeconds: 10
      supportedModelFormats:
        - name: triton
          version: "1"

    Инструкции по использованию:

    1. Создайте ClusterServingRuntime: примените YAML-конфигурацию выше с помощью kubectl apply -f triton-runtime.yaml
    2. Подготовьте модель: убедитесь, что ваша модель находится в формате, поддерживаемом Triton (например, TensorFlow, PyTorch, ONNX)
    3. Установите фреймворк модели: в репозитории модели установите метаданные фреймворка в triton, чтобы соответствовать полю supportedModelFormats
    4. Создайте сервис инференса: при публикации сервиса инференса выберите среду Triton из выпадающего списка сред выполнения

    MindIE (Ascend NPU 310P)

    MindIE специально разработан для аппаратного обеспечения Huawei Ascend. Его конфигурация значительно отличается в управлении ресурсами и метаданными.

    1. ClusterServingRuntime

    # Это пример YAML для среды Ascend NPU
    kind: ClusterServingRuntime
    apiVersion: serving.kserve.io/v1alpha1
    metadata:
      annotations:
        cpaas.io/display-name: mindie-2.2RC1
      labels:
        cpaas.io/accelerator-type: npu
        cpaas.io/cann-version: 8.3.0
        cpaas.io/runtime-class: mindie
      name: mindie-2.2rc1-310p
    spec:
      containers:
        - command:
            - bash
            - -c
            - |
              REAL_SCRIPT=$(echo "$RAW_SCRIPT" | sed 's/__LT__/\x3c/g')
              echo "$REAL_SCRIPT" > /tmp/startup.sh
              chmod +x /tmp/startup.sh
              
              if [ ! -d "${MODEL_PATH}" ]; then
                  MODEL_DIR="/mnt/models"
                  echo "[WARNING] Каталог модели ${MODEL_PATH} не найден, используется ${MODEL_DIR}"
                  MODEL_PATH="${MODEL_DIR}"
              fi
    
              CONFIG_FILE="${MODEL_PATH}/config.json"
              echo "Проверка файла: ${CONFIG_FILE}"
    
              ls -ld "${MODEL_PATH}"
              chmod -R 755 "${MODEL_PATH}"
              echo "Исправление прав доступа MODEL_PATH..."
              ls -ld "${MODEL_PATH}"
    
              /tmp/startup.sh --model-name "${MODEL_NAME}" --model-path "${MODEL_PATH}" --ip "${MY_POD_IP}"
          env:
            - name: RAW_SCRIPT
              value: |
                #!/bin/bash
                #
                #  Copyright 2024 Huawei Technologies Co., Ltd
                #
                #  Licensed under the Apache License, Version 2.0 (the "License");
                #  you may not use this file except в соответствии с лицензией.
                #  Вы можете получить копию лицензии по адресу:
                #
                #  http://www.apache.org/licenses/LICENSE-2.0
                #
                #  Если не требуется по закону или согласовано в письменной форме,
                #  программное обеспечение распространяется "КАК ЕСТЬ", без каких-либо гарантий.
                #  Подробнее см. в лицензии.
                #  ============================================================================
                #
    
                ##
                # Инструкция по скрипту
                ##
                ### Имя:
                ### run_mindie.sh - запуск сервиса MindIE для конкретной модели
                ###
                ### Использование:
                ###   bash run_mindie.sh --model-name xxx --model-path /path/to/model
                ###
                ### Обязательно:
                ###   --model-name             : имя модели для идентификации сервиса MindIE.
                ###   --model-path             : путь к модели с необходимыми файлами (yaml/conf.json/tokenizer/vocab и др.).
                ### Опции:
                ###   --help                   : показать это сообщение.
                ###   --ip                     : IP для REST интерфейса бизнес-плана MindIE, по умолчанию: 127.0.0.1.
                ###   --port                   : порт для REST интерфейса бизнес-плана MindIE, по умолчанию: 1025.
                ###   --management-ip          : IP для REST интерфейса управления MindIE, по умолчанию: 127.0.0.2.
                ###   --management-port        : порт для REST интерфейса управления MindIE, по умолчанию: 1026.
                ###   --metrics-port           : порт для мониторинга производительности, по умолчанию: 1027.
                ###   --max-seq-len            : максимальная длина последовательности, по умолчанию: 2560.
                ###   --max-iter-times         : максимальная длина вывода модели, по умолчанию: 512.
                ###   --max-input-token-len    : максимальная длина токена, по умолчанию: 2048.
                ###   --max-prefill-tokens     : количество входных токенов в текущем батче при prefill, по умолчанию: 8192.
                ###   --truncation             : проверка параметров, по умолчанию: false.
                ###   --template-type          : тип рассуждения, по умолчанию: "Standard"
                ###   --max-preempt-count      : максимальное число прерываемых запросов в батче, по умолчанию: 0.
                ###   --support-select-batch   : стратегия выбора батча, по умолчанию: false.
                ###   --npu-mem-size           : верхний предел размера KV Cache в NPU, по умолчанию: 8.
                ###   --max-prefill-batch-size : максимальный размер батча prefill, по умолчанию: 50.
                ###   --world-size             : количество карт для инференса.
                ###                             1. Если не задано, используется конфигурация из YAML: dp*mp*pp.
                ###                             2. Если задано, изменяет конфигурацию параллелизма: dp:1 mp:worldSize pp:1.
                ###   --ms-sched-host          : IP MS Scheduler, по умолчанию: 127.0.0.1.
                ###   --ms-sched-port          : порт MS Scheduler, по умолчанию: 8119.
                ### Для подробностей смотрите MindIE homepage: https://www.hiascend.com/document/detail/zh/mindie/10RC3/mindiellm/llmdev/mindie_llm0004.html
                help() {
                  awk -F'### ' '/^###/ { print $2 }' "$0"
                }
    
                if [[ $# == 0 ]] || [[ "$1" == "--help" ]]; then
                  help
                  exit 1
                fi
    
                ##
                # Получение информации об устройстве
                ##
                total_count=$(npu-smi info -l | grep "Total Count" | awk -F ':' '{print $2}' | xargs)
    
                if [[ -z "$total_count" ]]; then
                    echo "Ошибка: не удалось получить информацию об устройстве. Проверьте доступность npu-smi для текущего пользователя (id 1001) или занятость устройства."
                    exit 1
                fi
    
                echo "Обнаружено устройств: $total_count!"
    
                ##
                # Установка переменных окружения toolkit
                ##
                echo "Установка переменных окружения toolkit..."
                if [[ -f "/usr/local/Ascend/ascend-toolkit/set_env.sh" ]];then
                                source /usr/local/Ascend/ascend-toolkit/set_env.sh
                        else
                                echo "Пакет ascend-toolkit неполный, проверьте его."
                                exit 1
                        fi
                echo "Переменные окружения toolkit установлены!"
    
                ##
                # Установка переменных окружения MindIE
                ##
                echo "Установка переменных окружения MindIE..."
                if [[ -f "/usr/local/Ascend/mindie/set_env.sh" ]];then
                                source /usr/local/Ascend/mindie/set_env.sh
                        else
                                echo "Пакет mindie неполный, проверьте его."
                                exit 1
                        fi
                echo "Переменные окружения MindIE установлены!"
    
                ##
                # Переменные окружения MS по умолчанию
                ##
    
                # Установка PYTHONPATH
                MF_SCRIPTS_ROOT=$(realpath "$(dirname "$0")")
                export PYTHONPATH=$MF_SCRIPTS_ROOT/../:$PYTHONPATH
    
                ##
                # Получение аргументов и изменение config.json
                ##
                export MIES_INSTALL_PATH=/usr/local/Ascend/mindie/latest/mindie-service
                CONFIG_FILE=${MIES_INSTALL_PATH}/conf/config.json
                echo "Путь к конфигу MindIE Service:$CONFIG_FILE"
                # настройки по умолчанию
                BACKEND_TYPE="atb"
                MAX_SEQ_LEN=2560
                MAX_PREFILL_TOKENS=8192
                MAX_ITER_TIMES=512
                MAX_INPUT_TOKEN_LEN=2048
                TRUNCATION=false
                HTTPS_ENABLED=false
                MULTI_NODES_INFER_ENABLED=false
                NPU_MEM_SIZE=8
                MAX_PREFILL_BATCH_SIZE=50
                TEMPLATE_TYPE="Standard"
                MAX_PREEMPT_COUNT=0
                SUPPORT_SELECT_BATCH=false
                IP_ADDRESS="127.0.0.1"
                PORT=8080
                MANAGEMENT_IP_ADDRESS="127.0.0.2"
                MANAGEMENT_PORT=1026
                METRICS_PORT=1027
    
                # изменение конфигурации
                while [[ "$#" -gt 0 ]]; do
                    case $1 in
                        --model-path) MODEL_WEIGHT_PATH="$2"; shift ;;
                        --model-name) MODEL_NAME="$2"; shift ;;
                        --max-seq-len) MAX_SEQ_LEN="$2"; shift ;;
                        --max-iter-times) MAX_ITER_TIMES="$2"; shift ;;
                        --max-input-token-len) MAX_INPUT_TOKEN_LEN="$2"; shift ;;
                        --max-prefill-tokens) MAX_PREFILL_TOKENS="$2"; shift ;;
                        --truncation) TRUNCATION="$2"; shift ;;
                        --world-size) WORLD_SIZE="$2"; shift ;;
                        --template-type) TEMPLATE_TYPE="$2"; shift ;;
                        --max-preempt-count) MAX_PREEMPT_COUNT="$2"; shift ;;
                        --support-select-batch) SUPPORT_SELECT_BATCH="$2"; shift ;;
                        --npu-mem-size) NPU_MEM_SIZE="$2"; shift ;;
                        --max-prefill-batch-size) MAX_PREFILL_BATCH_SIZE="$2"; shift ;;
                        --ip) IP_ADDRESS="$2"; shift ;;
                        --port) PORT="$2"; shift ;;
                        --management-ip) MANAGEMENT_IP_ADDRESS="$2"; shift ;;
                        --management-port) MANAGEMENT_PORT="$2"; shift ;;
                        --metrics-port) METRICS_PORT="$2"; shift ;;
                        --ms-sched-host) ENV_MS_SCHED_HOST="$2"; shift ;;
                        --ms-sched-port) ENV_MS_SCHED_PORT="$2"; shift ;;
                        *)
                            echo "Неизвестный параметр: $1"
                            echo "Проверьте ввод."
                            exit 1
                            ;;
                    esac
                    shift
                done
    
                if [ -z "$MODEL_WEIGHT_PATH" ] || [ -z "$MODEL_NAME" ]; then
                    echo "Ошибка: параметры --model-path и --model-name обязательны."
                    exit 1
                fi
                MODEL_NAME=${MODEL_NAME:-$(basename "$MODEL_WEIGHT_PATH")}
                echo "MODEL_NAME установлен в: $MODEL_NAME"
    
                WORLD_SIZE=$total_count
                NPU_DEVICE_IDS=$(seq -s, 0 $(($WORLD_SIZE - 1)))
    
                # проверка конфигурации
                if [[ "$BACKEND_TYPE" != "atb" ]]; then
                    echo "Ошибка: BACKEND должен быть 'atb'. Текущее значение: $BACKEND_TYPE"
                    exit 1
                fi
    
                if [[ ! "$IP_ADDRESS" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] ||
                  [[ ! "$MANAGEMENT_IP_ADDRESS" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
                    echo "Ошибка: IP_ADDRESS и MANAGEMENT_IP_ADDRESS должны быть валидными IP. Текущие значения: IP_ADDRESS=$IP_ADDRESS, MANAGEMENT_IP_ADDRESS=$MANAGEMENT_IP_ADDRESS"
                    exit 1
                fi
    
                if [[ ! "$PORT" =~ ^[0-9]+$ ]] || (( PORT __LT__ 1025 || PORT > 65535 )) ||
                  [[ ! "$MANAGEMENT_PORT" =~ ^[0-9]+$ ]] || (( MANAGEMENT_PORT __LT__ 1025 || MANAGEMENT_PORT > 65535 )); then
                    echo "Ошибка: PORT и MANAGEMENT_PORT должны быть целыми числами от 1025 до 65535. Текущие значения: PORT=$PORT, MANAGEMENT_PORT=$MANAGEMENT_PORT"
                    exit 1
                fi
    
                if [ "$MAX_PREFILL_TOKENS" -lt "$MAX_SEQ_LEN" ]; then
                    MAX_PREFILL_TOKENS=$MAX_SEQ_LEN
                    echo "MAX_PREFILL_TOKENS меньше MAX_SEQ_LEN. Устанавливаем MAX_PREFILL_TOKENS в $MAX_SEQ_LEN"
                fi
    
                MODEL_CONFIG_FILE="${MODEL_WEIGHT_PATH}/config.json"
                if [ ! -f "$MODEL_CONFIG_FILE" ]; then
                    echo "Ошибка: файл config.json не найден в $MODEL_WEIGHT_PATH."
                    exit 1
                fi
                chmod 600 "$MODEL_CONFIG_FILE"
                # обновление конфигурационного файла
                chmod u+w ${MIES_INSTALL_PATH}/conf/
                sed -i "s/\"backendType\"\s*:\s*\"[^\"]*\"/\"backendType\": \"$BACKEND_TYPE\"/" $CONFIG_FILE
                sed -i "s/\"modelName\"\s*:\s*\"[^\"]*\"/\"modelName\": \"$MODEL_NAME\"/" $CONFIG_FILE
                sed -i "s|\"modelWeightPath\"\s*:\s*\"[^\"]*\"|\"modelWeightPath\": \"$MODEL_WEIGHT_PATH\"|" $CONFIG_FILE
                sed -i "s/\"maxSeqLen\"\s*:\s*[0-9]*/\"maxSeqLen\": $MAX_SEQ_LEN/" "$CONFIG_FILE"
                sed -i "s/\"maxPrefillTokens\"\s*:\s*[0-9]*/\"maxPrefillTokens\": $MAX_PREFILL_TOKENS/" "$CONFIG_FILE"
                sed -i "s/\"maxIterTimes\"\s*:\s*[0-9]*/\"maxIterTimes\": $MAX_ITER_TIMES/" "$CONFIG_FILE"
                sed -i "s/\"maxInputTokenLen\"\s*:\s*[0-9]*/\"maxInputTokenLen\": $MAX_INPUT_TOKEN_LEN/" "$CONFIG_FILE"
                sed -i "s/\"truncation\"\s*:\s*[a-z]*/\"truncation\": $TRUNCATION/" "$CONFIG_FILE"
                sed -i "s|\(\"npuDeviceIds\"\s*:\s*\[\[\)[^]]*\(]]\)|\1$NPU_DEVICE_IDS\2|" "$CONFIG_FILE"
                sed -i "s/\"worldSize\"\s*:\s*[0-9]*/\"worldSize\": $WORLD_SIZE/" "$CONFIG_FILE"
                sed -i "s/\"httpsEnabled\"\s*:\s*[a-z]*/\"httpsEnabled\": $HTTPS_ENABLED/" "$CONFIG_FILE"
                sed -i "s/\"templateType\"\s*:\s*\"[^\"]*\"/\"templateType\": \"$TEMPLATE_TYPE\"/" $CONFIG_FILE
                sed -i "s/\"maxPreemptCount\"\s*:\s*[0-9]*/\"maxPreemptCount\": $MAX_PREEMPT_COUNT/" "$CONFIG_FILE"
                sed -i "s/\"supportSelectBatch\"\s*:\s*[a-z]*/\"supportSelectBatch\": $SUPPORT_SELECT_BATCH/" "$CONFIG_FILE"
                sed -i "s/\"multiNodesInferEnabled\"\s*:\s*[a-z]*/\"multiNodesInferEnabled\": $MULTI_NODES_INFER_ENABLED/" "$CONFIG_FILE"
                sed -i "s/\"maxPrefillBatchSize\"\s*:\s*[0-9]*/\"maxPrefillBatchSize\": $MAX_PREFILL_BATCH_SIZE/" "$CONFIG_FILE"
                sed -i "s/\"ipAddress\"\s*:\s*\"[^\"]*\"/\"ipAddress\": \"$IP_ADDRESS\"/" "$CONFIG_FILE"
                sed -i "s/\"port\"\s*:\s*[0-9]*/\"port\": $PORT/" "$CONFIG_FILE"
                sed -i "s/\"managementIpAddress\"\s*:\s*\"[^\"]*\"/\"managementIpAddress\": \"$MANAGEMENT_IP_ADDRESS\"/" "$CONFIG_FILE"
                sed -i "s/\"managementPort\"\s*:\s*[0-9]*/\"managementPort\": $MANAGEMENT_PORT/" "$CONFIG_FILE"
                sed -i "s/\"metricsPort\"\s*:\s*[0-9]*/\"metricsPort\": $METRICS_PORT/" $CONFIG_FILE
                sed -i "s/\"npuMemSize\"\s*:\s*-*[0-9]*/\"npuMemSize\": $NPU_MEM_SIZE/" "$CONFIG_FILE"
    
                ##
                # Запуск сервиса
                ##
                echo "Текущие настройки:"
                cat $CONFIG_FILE
                npu-smi info -m > ~/device_info
    
                ${MIES_INSTALL_PATH}/bin/mindieservice_daemon
            - name: MODEL_NAME
              value: '{{ index .Annotations "aml-model-repo" }}'
            - name: MODEL_PATH
              value: /mnt/models/{{ index .Annotations "aml-model-repo" }}
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
          image: swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:2.2.RC1-300I-Duo-py311-openeuler24.03-lts
          name: kserve-container
          resources:
            limits:
              cpu: 2
              memory: 6Gi
            requests:
              cpu: 2
              memory: 6Gi
          volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          startupProbe:
            failureThreshold: 60
            httpGet:
              path: /v1/models
              port: 8080
              scheme: HTTP
            periodSeconds: 10
            timeoutSeconds: 180
      supportedModelFormats:
        - name: transformers
          version: "1"
      volumes:
        - emptyDir:
            medium: Memory
            sizeLimit: 8Gi
          name: dshm
          

    2. Обязательные аннотации для InferenceService

    В отличие от других сред, MindIE обязательно требует добавления аннотаций в метаданные InferenceService на этапе финальной публикации. Это гарантирует корректное связывание планировщиком платформы аппаратуры NPU с сервисом.

    Ключ конфигурацииЗначениеНазначение
    storage.kserve.io/readonly"false"Включает доступ на запись к тому для хранения модели.

    3. Привилегии пользователя (доступ root)

    Из-за требований драйвера Ascend и слоя абстракции аппаратуры, образ MindIE должен запускаться от пользователя root. Убедитесь, что securityContext вашего ClusterServingRuntime или InferenceService настроен соответствующим образом:

    Примечание: В приведённом примере YAML для MindIE не указан securityContext, значит контейнер запускается с настройками по умолчанию образа (обычно root). В отличие от MLServer, где явно задан runAsNonRoot: true и runAsUser: 1000, MindIE требует root-привилегии для доступа к NPU.

    Comparison of Runtime Configurations

    Перед продолжением ознакомьтесь с этой таблицей, чтобы понять специфические требования разных сред выполнения:

    Среда выполненияЦелевая аппаратная платформаПоддерживаемые фреймворкиОсобые требования
    XinferenceCPU / NVIDIA GPUtransformers, pytorchОбязательно задать переменную окружения MODEL_FAMILY
    MLServerCPU / NVIDIA GPUsklearn, xgboost, mlflowСтандартная конфигурация
    TritonNVIDIA GPUtriton (TensorFlow, PyTorch, ONNX и др.)Стандартная конфигурация
    MindIEHuawei Ascend NPUmindspore, transformersОбязательно добавить аннотации NPU в InferenceService