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

    Introduction

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

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

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

    В этом разделе мы продемонстрируем расширение текущей AI платформы с помощью пользовательской среды выполнения сервиса инференса XInfernece для развертывания 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 "Need to set MODEL_PATH!"
                  exit 1
              fi
              if [ "${MODEL_ENGINE}" == "" ]; then
                  echo "Need to set MODEL_ENGINE!"
                  exit 1
              fi
              if [ "${MODEL_UID}" == "" ]; then
                  echo "Need to set MODEL_UID!"
                  exit 1
              fi
              if [ "${MODEL_FAMILY}" == "" ]; then
                  echo "Need to set 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 "waiting xinference-local server to become ready..."
                      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 "model load succeeded, waiting server process: ${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-файл для создания ресурса:

      Выполните в терминале с правами администратора кластера команду для применения 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 (например, «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 directory ${MODEL_PATH} not found, using ${MODEL_DIR} instead"
                  MODEL_PATH="${MODEL_DIR}"
              fi
    
              CONFIG_FILE="${MODEL_PATH}/config.json"
              echo "Checking for file: ${CONFIG_FILE}"
    
              ls -ld "${MODEL_PATH}"
              chmod -R 755 "${MODEL_PATH}"
              echo "Fixing MODEL_PATH permission..."
              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 in compliance with the License.
                #  You may obtain a copy of the License at
                #
                #  http://www.apache.org/licenses/LICENSE-2.0
                #
                #  Unless required by applicable law or agreed to in writing, software
                #  distributed under the License is distributed on an "AS IS" BASIS,
                #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                #  See the License for the specific language governing permissions and
                #  limitations under the License.
                #  ============================================================================
                #
    
                ##
                # Инструкция по скрипту
                ##
                ### Название:
                ### 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 адрес, привязанный к RESTful интерфейсу бизнес-плоскости MindIE сервера, значение по умолчанию: 127.0.0.1.
                ###   --port                   : порт, привязанный к RESTful интерфейсу бизнес-плоскости MindIE сервера, значение по умолчанию: 1025.
                ###   --management-ip          : IP адрес, привязанный к RESTful интерфейсу управляющей плоскости MindIE сервера, значение по умолчанию: 127.0.0.2.
                ###   --management-port        : порт, привязанный к RESTful интерфейсу управляющей плоскости 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. Установите worldsize = dp*mp*pp.
                ###                             2. Если задано, изменяет конфигурацию параллелизма в YAML: dp:1 mp:worldSize pp:1
                ###   --ms-sched-host          : IP адрес MS Scheduler, значение по умолчанию: 127.0.0.1.
                ###   --ms-sched-port          : порт MS Scheduler, значение по умолчанию: 8119.
                ### Для подробностей о конфигурации смотрите домашнюю страницу MindIE: 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 "Error: Unable to retrieve device info. Please check if npu-smi is available for current user (id 1001), or if you are specifying an occupied device."
                    exit 1
                fi
    
                echo "$total_count device(s) detected!"
    
                ##
                # Установка переменных окружения toolkit
                ##
                echo "Setting toolkit envs..."
                if [[ -f "/usr/local/Ascend/ascend-toolkit/set_env.sh" ]];then
                                source /usr/local/Ascend/ascend-toolkit/set_env.sh
                        else
                                echo "ascend-toolkit package is incomplete please check it."
                                exit 1
                        fi
                echo "Toolkit envs set succeeded!"
    
                ##
                # Установка переменных окружения MindIE
                ##
                echo "Setting MindIE envs..."
                if [[ -f "/usr/local/Ascend/mindie/set_env.sh" ]];then
                                source /usr/local/Ascend/mindie/set_env.sh
                        else
                                echo "mindie package is incomplete please check it."
                                exit 1
                        fi
                echo "MindIE envs set succeeded!"
    
                ##
                # Переменные окружения 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 path:$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 "Unknown parameter: $1"
                            echo "Please check your inputs."
                            exit 1
                            ;;
                    esac
                    shift
                done
    
                if [ -z "$MODEL_WEIGHT_PATH" ] || [ -z "$MODEL_NAME" ]; then
                    echo "Error: Both --model-path and --model-name are required."
                    exit 1
                fi
                MODEL_NAME=${MODEL_NAME:-$(basename "$MODEL_WEIGHT_PATH")}
                echo "MODEL_NAME is set to: $MODEL_NAME"
    
                WORLD_SIZE=$total_count
                NPU_DEVICE_IDS=$(seq -s, 0 $(($WORLD_SIZE - 1)))
    
                # проверка конфигурации
                if [[ "$BACKEND_TYPE" != "atb" ]]; then
                    echo "Error: BACKEND must be 'atb'. Current value: $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 "Error: IP_ADDRESS and MANAGEMENT_IP_ADDRESS must be valid IP addresses. Current values: 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 "Error: PORT and MANAGEMENT_PORT must be integers between 1025 and 65535. Current values: 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 was less than MAX_SEQ_LEN. Setting MAX_PREFILL_TOKENS to $MAX_SEQ_LEN"
                fi
    
                MODEL_CONFIG_FILE="${MODEL_WEIGHT_PATH}/config.json"
                if [ ! -f "$MODEL_CONFIG_FILE" ]; then
                    echo "Error: config.json file not found in $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 "Current configurations are displayed as follows:"
                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. Убедитесь, что в ClusterServingRuntime или InferenceService настроен соответствующий securityContext:

    Примечание: В приведённом выше примере 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