- Дата публикации
Как за 10 минут поднять локальный ИИ-сервис на Azure: гид по Foundry Local Model Catalog
Что нового
Microsoft показала на GitHub рабочий пример, который помогает развернуть первую языковую модель на Foundry Local поверх Azure Local за считанные минуты. Скрипт catalog_sample.py автоматизирует полный цикл:
- Читает каталог доступных моделей из Kubernetes ConfigMap.
- Создаёт кастомный ресурс
ModelDeploymentпо выбранной записи каталога. - Ждёт, пока развёртывание перейдёт в состояние Running + Ready (таймаут по умолчанию — 600 секунд).
- Запускает инференс через OpenAI‑совместимый эндпоинт
/v1/chat/completions. - При необходимости автоматически удаляет развёртывание.
Ключевые детали:
- Поддержка CPU и GPU‑конфигураций.
- Два рантайма инференса: ONNX-GenAI (
onnx) и vLLM (vllm). - Возможность поднять модель Phi‑4‑generic‑cpu «по умолчанию» одной командой.
- Полная совместимость с протоколом OpenAI API, включая работу через официальный Python SDK.
- Сценарий для запуска как внутри кластера, так и с ноутбука с доступом по
kubectl port-forward.
Это не просто демо, а готовый шаблон жизненного цикла модели в Kubernetes: от выбора в каталоге до реального запроса и последующей очистки.
Как это работает
Под капотом Foundry Local на Azure Local использует Kubernetes и собственный Inference Operator.
Архитектура
Есть две ключевые зоны:
-
Ваша рабочая станция
- Скрипт
catalog_sample.py. - Kubernetes‑клиент, который ходит в API‑сервер:
- читает ConfigMap с каталогом моделей;
- создаёт и отслеживает
ModelDeployment(CRD); - читает Secret с API‑ключом.
- HTTP‑клиент (
requestsили OpenAI SDK), который шлёт запросы на эндпоинт инференса:POST /v1/chat/completions;- авторизация через
Authorization: Bearer <API_KEY>.
- Скрипт
-
Кластер Kubernetes (Azure Local)
- Неймспейс
foundry-local-operator. - Inference Operator, который следит за кастомными ресурсами.
- ConfigMap
foundry-local-catalogсcatalog.json, синхронизированным из Azure AI Foundry. - CR
ModelDeployment, из которого оператор создаётDeployment + Service + Ingress. - Secret
<name>-api-keysс первичным и вторичным API‑ключами. - Pod модели: контейнер инференса + sidecar с TLS.
- Неймспейс
Поток работы скрипта
Сценарий реализует следующий pipeline:
-
Запрос каталога
Скрипт читает ConfigMap кластера с описанием всех доступных моделей (имя, версии, поддерживаемые рантаймы, типы вычислений). -
Создание ModelDeployment
На основе выбранной записи каталога скрипт формирует CRModelDeploymentв namespacefoundry-local-operator. Оператор:- при первом обращении выполняет «ленивую регистрацию» — создаёт объект
Modelиз каталога; - разворачивает Deployment, Service и Ingress для выбранной модели и рантайма.
- при первом обращении выполняет «ленивую регистрацию» — создаёт объект
-
Ожидание готовности
Скрипт опрашивает статусModelDeployment, пока тот не станет Running + Ready или не истечёт таймаут (по умолчанию 600 секунд). Если образ модели ещё не скачан, развёртывание может подзависнуть в состоянии Creating — в этом случае нужно смотреть события Pod. -
Инференс через OpenAI‑совместимый API
После готовности скрипт отправляет запрос на/v1/chat/completions. Эндпоинт полностью совместим с OpenAI API: тот же форматmessages,model,max_tokensи т.д. -
Очистка
По умолчанию скрипт удаляетModelDeploymentпосле инференса. Можно отключить это флагом--skip-cleanupи держать сервис в онлайне.
Используемые компоненты
Чтобы всё это работало, нужны:
- Kubernetes‑кластер с установленным Foundry Local.
- Azure Local с AKS или любой Arc‑подключённый Kubernetes‑кластер.
- Inference Operator Foundry Local, установленный через Helm.
cert-managerиtrust-managerдля TLS.- Настроенный
kubectlс правами:- читать ConfigMaps, Secrets, CRDs;
- создавать/получать/удалять
modeldeployments.foundrylocal.azure.comвfoundry-local-operator.
- Python 3.9+ с
pip.
Что это значит для вас
Этот пример полезен, если вы:
- Разворачиваете ИИ‑сервисы на своём Kubernetes и хотите минимизировать ручную работу.
- Тестируете Foundry Local и Azure Local и хотите быстро получить живой OpenAI‑совместимый эндпоинт.
- Пишете свои операторы/автоматизацию и ищете образец полного жизненного цикла модели.
Для каких задач подходит
- Быстрый POC: за один запуск вы проходите путь от каталога до реального ответа модели.
- Интеграция в существующие приложения: эндпоинт совместим с OpenAI API, поэтому можно переиспользовать уже написанный клиентский код.
- Эксперименты с CPU/GPU и рантаймами: легко сравнить ONNX-GenAI и vLLM на одних и тех же моделях и запросах.
- Обучение команды: хороший учебный пример для разработчиков и DevOps, которые только заходят в тему K8s + LLM.
Где не стоит применять
- Продакшн‑нагрузка без доработок: пример не закрывает вопросы масштабирования, мониторинга, логирования, ротации ключей и продакшн‑TLS.
- Высоконагруженные сценарии без тюнинга: вам придётся отдельно настраивать ресурсы Pod, авто‑скейлинг и лимиты.
- Облачные среды без доступа к Kubernetes: пример рассчитан на тех, у кого уже есть кластер и доступ по
kubectl.
Доступность из России
Проект живёт на GitHub и использует Azure Local и Azure AI Foundry. Для доступа к репозиторию и облачной части Azure в России часто нужен VPN. Если ваша инфраструктура уже развёрнута и настроена в корпоративной сети, доступ может обеспечивать внутренний периметр — это зависит от политики вашей организации.
Место на рынке
Сценарий Foundry Local на Azure Local конкурирует не с одной моделью, а с целым классом решений: это альтернатива ручной сборке стека «Kubernetes + оператор + модель + сервис».
По ключевым параметрам:
-
Интерфейс API.
Эндпоинт полностью совместим с OpenAI API. Это упрощает миграцию с GPT‑линеек: можно перенастроитьbase_urlи ключ, не меняя формат запросов. -
Рантаймы.
ONNX-GenAI и vLLM уже зарекомендовали себя в сообществе как быстрые и эффективные движки для LLM. В примере нет числовых бенчмарков, но оба решения активно используют в продакшн‑сценариях, особенно vLLM на GPU. -
Интеграция с Azure AI Foundry.
Каталог моделей синхронизируется из Azure AI Foundry в ConfigMap кластера. Это даёт централизованное управление модельным зоопарком, чего не хватает многим самодельным решениям. -
Управление жизненным циклом через CRD.
Подход сModelDeploymentхорошо стыкуется с DevOps‑практиками: можно описывать развёртывания в Git, использовать GitOps, политики и т.д.
Если вы уже используете OpenAI API напрямую, этот путь интересен, когда нужно перенести инференс на собственный кластер и сохранить привычный протокол.
Установка
Ниже — полный набор шагов из примера, без сокращений.
1. Клонируем репозиторий
git clone https://github.com/Azure-Samples/foundry-local-model-catalog.git
cd foundry-local-model-catalog
2. Устанавливаем зависимости
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -r requirements.txt
3. Проверяем доступ к кластеру
# Confirm you can reach the cluster
kubectl get pods -n foundry-local-operator
# Verify the Inference Operator CRDs are installed
kubectl get crd | grep foundry
Если эти команды не проходят, сначала нужно настроить кластер и Inference Operator.
Как запустить
Базовый сценарий: развернуть Phi‑4 на CPU, сделать запрос и очистить
# Default: deploy Phi-4 on CPU, run inference, clean up
python catalog_sample.py
Скрипт:
- выберет модель
Phi-4-generic-cpuиз каталога; - создаст
ModelDeploymentс рантаймом по умолчанию (ONNX-GenAI); - дождётся состояния Running + Ready;
- отправит запрос с дефолтным промптом;
- удалит развёртывание.
Примеры использования
# List all available models in the catalog (no deployment)
python catalog_sample.py --catalog-only
# Deploy Phi-4 on GPU
python catalog_sample.py --model Phi-4-generic-gpu --compute gpu
# Deploy Phi-4-mini with the vLLM runtime on GPU
python catalog_sample.py --model Phi-4-mini-instruct --compute gpu --runtime vllm
# Deploy and keep the model running after inference
python catalog_sample.py --skip-cleanup
# Two-step flow (running from your laptop):
python catalog_sample.py --deploy-only # Deploy and wait for ready
# In another terminal:
kubectl port-forward svc/phi-4-generic-cpu 5000:5000 -n foundry-local-operator
python catalog_sample.py --infer-only --endpoint https://localhost:5000 --insecure
# Use a custom prompt
python catalog_sample.py --prompt " Explain quantum computing in two sentences. "
Выбор рантайма
Разработчики предлагают простое правило:
- ONNX-GenAI (
onnx) — используйте на узлах только с CPU, для компактных моделей или когда у вас один основной сценарий использования. - vLLM (
vllm) — используйте на GPU‑узлах для высокопроизводительного обслуживания больших моделей и множественных пользователей.
Оба рантайма отдают один и тот же OpenAI‑совместимый REST‑эндпоинт, поэтому клиентский код не меняется.
Запуск с ноутбука вне кластера
Если вы запускаете скрипт не изнутри кластера, а со своей машины, используйте двухшаговый сценарий:
# Step 1: Deploy the model and wait for it to become ready
python catalog_sample.py --deploy-only
# Step 2: In a separate terminal, set up port-forwarding
kubectl port-forward svc/phi-4-generic-cpu 5000:5000 -n foundry-local-operator
# Step 3: Run inference using the local endpoint
python catalog_sample.py --infer-only --endpoint https://localhost:5000 --insecure
Foundry Local использует самоподписанные TLS‑сертификаты внутри кластера. Флаг --insecure отключает проверку сертификата — аналогично -k в curl. В боевой среде лучше настроить полноценные TLS‑сертификаты.
Очистка
По умолчанию пример сам удаляет развёртывание после инференса. Чтобы оставить сервис работать:
python catalog_sample.py --skip-cleanup
Позже можно удалить развёртывание вручную:
kubectl delete modeldeployment <deployment-name> -n foundry-local-operator
Параметры командной строки
Скрипт catalog_sample.py принимает набор флагов, которые управляют моделью, рантаймом и режимом работы.
Flag Default Description
--model Phi-4-generic-cpu Catalog model name
--version (auto-detect) Catalog model version
--compute cpu Compute type ( cpu or gpu )
--runtime onnx Inference runtime ( onnx or vllm ). vllm requires --compute gpu .
--deployment-name (derived from model) Custom deployment name
--namespace foundry-local-operator Kubernetes namespace
--endpoint (in-cluster DNS) Inference endpoint URL (required when running outside the cluster)
--prompt "What is the capital of France? Reply in one sentence." Prompt to send
--timeout 600 Deployment readiness timeout (seconds)
--catalog-only false List catalog and exit
--deploy-only false Deploy the model and exit (skip inference)
--infer-only false Skip deployment, run inference against existing deployment
--skip-cleanup false Keep deployment running after inference
--insecure false Skip TLS certificate verification (for self-signed certs)
Использование OpenAI Python SDK
Если вы уже пишете под OpenAI API, можно не трогать HTTP‑запросы вручную и подключиться через официальный Python SDK. Для этого установите дополнительные зависимости:
pip install openai httpx
Затем подключитесь к локальному эндпоинту после развёртывания модели и настройки port‑forward:
import httpx
from openai import OpenAI
# After deploying the model and setting up port-forward:
# kubectl port-forward svc/phi-4-generic-cpu 5000:5000 -n foundry-local-operator
client = OpenAI(
base_url="https://localhost:5000/v1",
api_key="<YOUR_API_KEY>", # From: kubectl get secret phi-4-generic-cpu-api-keys ...
http_client=httpx.Client(verify=False), # Self-signed certs
)
response = client.chat.completions.create(
model="Phi-4-generic-cpu:1",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"},
],
max_tokens=256,
)
print(response.choices[0].message.content)
Ключ (api_key) нужно взять из секрета Kubernetes:
kubectl get secret phi-4-generic-cpu-api-keys -n foundry-local-operator -o jsonpath='{.data.primary-key}' | base64 -d
Ключевые концепции
Разработчики опираются на несколько базовых сущностей:
- Inference Operator — Kubernetes‑оператор, который управляет жизненным циклом ИИ‑моделей: реагирует на CRD, создаёт Deployment, Service, Ingress и Secrets.
- Model Catalog — ConfigMap, который кэширует метаданные моделей из Azure AI Foundry. Скрипт читает его, чтобы узнать, какие модели доступны и как их разворачивать.
- ModelDeployment — CRD, который описывает желаемое состояние развёрнутой модели и служит источником правды для оператора.
- Lazy Registration — оператор автоматически создаёт объект
Modelпри первом развёртывании записи из каталога. - API Key Auth — при создании развёртывания оператор генерирует пару ключей и кладёт их в Secret
<name>-api-keys.
Траблшутинг
Если что-то пошло не так, разработчики предлагают такие шаги:
-
CRD не найден
Установите Inference Operator через Helm. -
ConfigMap с каталогом не найден
Запустите синхронизацию каталога:kubectl create job --from=cronjob/foundry-local-catalog-sync manual-sync -n foundry-local-operator -
Развёртывание зависло в состоянии Creating
Скорее всего, идёт загрузка образа модели. Посмотрите события:kubectl describe mdep <name> -n foundry-local-operator -
Развёртывание в состоянии Error
Проверьте сообщение об ошибке через ту же командуkubectl describe mdep <name> -n foundry-local-operator. -
Connection refused при инференсе
Убедитесь, что настроили port‑forward на нужный сервис:kubectl port-forward svc/<name> 5000:5000 -n foundry-local-operator -
401 Unauthorized
Проверьте, что используете корректный API‑ключ из секрета:kubectl get secret <name>-api-keys -n foundry-local-operator -o jsonpath='{.data.primary-key}' | base64 -d
Лицензия и вклад
Проект открыт на GitHub под лицензией MIT. Можно свободно использовать пример в своих продуктах и адаптировать под инфраструктуру.
Если хотите доработать скрипт или оператор, Microsoft просит оформить Contributor License Agreement (CLA). Подробности лежат в CONTRIBUTING.md в репозитории, сама лицензия — в LICENSE.md.