FHE Inference on SageMaker: Полный гайд 2026 | AiManual
AiManual Logo Ai / Manual.
14 Июн 2026 Гайд

End-to-End Encrypted ML Inference with Fully Homomorphic Encryption on Amazon SageMaker

Пошаговое руководство по развертыванию полностью гомоморфного шифрования (FHE) для ML-инференса на Amazon SageMaker. Реальная privacy-архитектура с кодом и нюан

Реклама
cliv1

Ваши данные никто не должен видеть. Даже модель.

Звучит параноидально? А теперь представьте: вы передаете медицинские снимки облачному ML-сервису. Врач-нейросеть ставит диагноз. Но что, если кто-то перехватит данные по пути? Или сам провайдер (AWS) теоретически может заглянуть в RAM инстанса. Стандартное шифрование в покое и в транзите — это база, но во время вычислений данные расшифровываются. Полностью гомоморфное шифрование (FHE) закрывает эту дыру: вычисления идут прямо на зашифрованных числах. Результат — зашифрован, и только клиент с ключом может его прочитать.

В 2026 году FHE всё ещё медленнее обычного инференса в 100–1000 раз, но для задач с высокими требованиями к конфиденциальности (финансы, здравоохранение, госсектор) это единственный легальный путь. Amazon SageMaker позволяет запускать кастомные контейнеры, так что теоретически можно воткнуть FHE-библиотеку. На практике — это ад. Давайте разберем, как построить работающий пайплайн, не сойдя с ума.

Дисклеймер: FHE — это не серебряная пуля. Он не подходит для трансформеров с миллиардами параметров (пока). Мы будем работать с небольшой нейросетью на табличных данных. Если вам нужно защитить LLM — посмотрите в сторону обучения с Liger Kernels и шифрования на уровне сети через AWS PrivateLink. Здесь же — максимальный privacy.

Почему FHE и SageMaker — это брак, заключенный на небесах (и в аду)

SageMaker из коробки умеет шифровать данные на S3 и в каналах связи, но во время инференса модель имеет доступ к сырым значениям. Даже Nitro Enclaves не спасают, если вы не доверяете AWS (а некоторые регуляторы не доверяют). FHE переносит доверие на математику: клиент шифрует данные локально, отправляет зашифрованный тензор, SageMaker выполняет модель, возвращает зашифрованный результат. Никто, кроме клиента, не знает, что внутри.

Проблема: SageMaker не поддерживает FHE нативно. Придется собрать кастомный образ с библиотекой (Concrete-ML или OpenFHE), скомпилировать модель для FHE, и в inference-скрипте обрабатывать зашифрованные тензоры. Да, это всё еще исследовательская зона. Но в 2026-м Concrete-ML уже стабильно работает на CPU и даже умеет Quantization Aware Training (QAT) для повышения скорости.

Кстати, если вам интересен полный цикл кастомизации моделей от претрейна до DPO на SageMaker — там тоже много подводных камней, но без криптографии. Вернемся к FHE.

Архитектура: без компромиссов

Вот как выглядит data flow:

  1. Клиент (ваше приложение) генерирует пару ключей (секретный + вычислений).
  2. Клиент шифрует входные данные (числа или one-hot векторы) с помощью открытого ключа.
  3. Зашифрованный тензор отправляется в SageMaker Endpoint через HTTPS.
  4. Контейнер с FHE-моделью выполняет вычисления на зашифрованных данных (без расшифровки).
  5. Зашифрованный результат возвращается клиенту.
  6. Клиент расшифровывает результат секретным ключом.

Ключевой момент: модель должна быть скомпилирована в FHE-совместимую схему. Большинство обычных нейросетей не работают — нужны только линейные слои, ReLU (через полиномиальную аппроксимацию), и никаких softmax в чистом виде. Concrete-ML умеет автоматически конвертировать стандартные sklearn/pytorch модели в FHE. Звучит магически, но работает только для маленьких сеток.

Предупреждение: FHE — это ресурсоемко. Каждая операция умножения на шифротексте требует swap-шума и bootstrap-процедуры. SageMaker t3.medium может не справиться — используйте хотя бы m5.xlarge или graviton. И тайм-аут эндпоинта ставьте 300 секунд.

Пошаговый план: от установки до эндпоинта

1Настройка окружения и установка Concrete-ML

Сначала поднимите виртуалку с Python 3.12 (2026 — уже не новинка, но для совместимости лучше 3.11). Concrete-ML последней версии (на момент 14.06.2026 — это v1.8.2, поддерживающая BFV и CKKS). Установите:

pip install concrete-ml==1.8.2 numpy==1.26.4 scikit-learn==1.5.3

Да, FHE-библиотеки всё ещё не любят последние numpy. Привыкайте.

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

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from concrete.ml.sklearn import LogisticRegression

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model = LogisticRegression()
model.fit(X_train, y_train)

2Компиляция модели для FHE

Теперь превратим обычную модель в FHE-совместимую. Concrete-ML делает это через compile:

from concrete.ml.deployment import FHEModelClient, FHEModelServer
import numpy as np

# Сохраняем модель в формате, понятном для FHE
model.compile(X_train)
model.save("./fhe_model")

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

Важно: компиляция занимает некоторое время (от секунд до минут). Она подбирает параметры шифрования (размер polynomial modulus, количество уровней). Если модель слишком глубокая — компиляция выдаст ошибку. Выход — упрощать архитектуру или использовать Quantized Neural Networks.

3Сборка Docker-образа для SageMaker

SageMaker требует, чтобы в контейнере были предустановлены библиотеки и inference-скрипт. Создайте Dockerfile на основе официального образа SageMaker PyTorch (или просто Ubuntu + Python):

FROM pytorch/pytorch:2.3.0-cuda12.1-cudnn8-runtime  # используем CPU, FHE не на GPU
RUN pip install concrete-ml==1.8.2 numpy==1.26.4
COPY fhe_model /opt/ml/model/fhe_model
COPY inference.py /opt/ml/code/inference.py
ENV SAGEMAKER_PROGRAM inference.py

Скрипт inference.py должен загружать модель, принимать зашифрованный payload, выполнять инференс и возвращать зашифрованный результат. Пример:

import json
import numpy as np
from concrete.ml.deployment import FHEModelServer

model_dir = "/opt/ml/model"
fhe_server = FHEModelServer(path_dir=model_dir + "/fhe_model")

def model_fn(model_dir):
    return fhe_server

def predict_fn(input_data, model):
    # input_data — зашифрованный тензор в виде bytes или base64
    encrypted_result = model.run(input_data)  # выполняет вычисления в FHE
    return {"prediction": encrypted_result.hex()}

Обратите внимание: FHEModelServer не нужен секретный ключ, только открытый. Это безопасно.

Соберите образ и отправьте в ECR:

aws ecr create-repository --repository-name fhe-inference
$(aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin .dkr.ecr.us-east-1.amazonaws.com)
docker build -t fhe-inference .
docker tag fhe-inference:latest .dkr.ecr.us-east-1.amazonaws.com/fhe-inference:latest
docker push .dkr.ecr.us-east-1.amazonaws.com/fhe-inference:latest

4Регистрация модели и создание эндпоинта

Теперь через boto3 (или консоль) создайте модель SageMaker, укажите образ из ECR, и разверните эндпоинт. Пример с OpenAI-совместимым API тут не подойдет — нам нужен прямой вызов.

import boto3

sm = boto3.client("sagemaker", region_name="us-east-1")

model_name = "fhe-iris-model"
endpoint_config_name = "fhe-iris-config"
endpoint_name = "fhe-iris-endpoint"

# Создаем модель
sm.create_model(
    ModelName=model_name,
    PrimaryContainer={
        "Image": ".dkr.ecr.us-east-1.amazonaws.com/fhe-inference:latest",
        "ModelDataUrl": "s3://my-bucket/fhe-model.tar.gz",  # если модель загружена отдельно
    },
    ExecutionRoleArn="arn:aws:iam::xxx:role/SageMakerExecutionRole"
)

# Конфигурация эндпоинта (выберите инстанс побольше)
sm.create_endpoint_config(
    EndpointConfigName=endpoint_config_name,
    ProductionVariants=[{
        "VariantName": "default",
        "ModelName": model_name,
        "InstanceType": "ml.m5.xlarge",
        "InitialInstanceCount": 1
    }]
)

sm.create_endpoint(
    EndpointName=endpoint_name,
    EndpointConfigName=endpoint_config_name
)

Подождите статус InService (минут 5–10).

5Клиент: шифруем, отправляем, расшифровываем

На стороне клиента используем FHEModelClient:

from concrete.ml.deployment import FHEModelClient
import requests

# Загружаем клиентскую часть (содержит открытый ключ)
fhe_client = FHEModelClient(path_dir="./fhe_model")

# Шифруем данные (пример — первый образец ириса)
sample = np.array([[5.1, 3.5, 1.4, 0.2]])
encrypted_input = fhe_client.quantize_encrypt_serialize(sample)  # возвращает bytes

# Отправляем POST запрос к эндпоинту
response = requests.post(
    url="https://runtime.sagemaker.us-east-1.amazonaws.com/endpoints/fhe-iris-endpoint/invocations",
    data=encrypted_input,
    headers={"Content-Type": "application/octet-stream"},
    auth=SigV4Auth(...)  # используйте boto3 для подписи
)
encrypted_result_hex = response.json()["prediction"]
encrypted_result = bytes.fromhex(encrypted_result_hex)

# Расшифровываем
decrypted = fhe_client.deserialize_decrypt(encrypted_result)
print("Predicted class:", np.argmax(decrypted))

Готово. Теперь ни AWS, ни кто-либо еще не знает, какие данные вы отправили и что предсказала модель. Только вы.

💡
Для продакшена рекомендую дополнительно завернуть эндпоинт в VPC и использовать PrivateLink — см. гайд по ML-песочнице. А для отслеживания метрик — сквозной трекинг через DVC и MLflow.

Типичные грабли и как их избежать

  • Таймауты. SageMaker эндпоинт по умолчанию ждет 60 секунд. FHE-инференс может длиться 2–5 минут. Увеличьте: при создании модели укажите InferenceExecutionTimeoutInSeconds=600.
  • Размер ответа. Зашифрованные результаты могут весить мегабайты. Установите InvocationMaxResponseSizeInBytes до 10 MB.
  • Ошибки компиляции. Если в модели есть нелинейности, которые не поддерживаются (например, GELU), компиляция упадет. Используйте concrete.ml.torch.compile с опцией use_dynamic_tiling=False.
  • Размер ключа. Секретный ключ клиента генерируется на лету — сохраните его в безопасном месте. Если потеряете — данные не расшифровать.

Еще одна боль: SageMaker не поддерживает передачу бинарных данных напрямую через API Gateway. Используйте SageMaker Runtime с InvokeEndpoint через boto3, а не HTTP-вызовы с raw bytes. Пример с invoke_endpoint:

client = boto3.client("sagemaker-runtime")
response = client.invoke_endpoint(
    EndpointName=endpoint_name,
    Body=encrypted_input,
    ContentType="application/octet-stream"
)
encrypted_result = response["Body"].read()

Так надёжнее и проще с аутентификацией.

Что дальше? (спойлер: не останавливайтесь)

FHE на SageMaker — это только первый шаг. Следующий уровень — приватное обучение с Federated Learning + FHE. Представьте: несколько клиентов шифруют свои данные, сервер на SageMaker обучает модель на зашифрованных градиентах, и никто не видит чужие данные. Такие эксперименты уже проводятся с Feature Store и Iceberg для распределённых данных.

Ещё один вектор — квантование моделей до 2–3 бит для ускорения FHE. Concrete-ML поддерживает QAT, и на датасетах типа CIFAR-10 точность падает всего на 2–3%. Попробуйте развернуть ASR модель с FHE — будет весело (и медленно).

Но главный неочевидный совет: не шифруйте всё подряд. Выделите критичные признаки (например, ID пациента, диагноз) и шифруйте только их. Остальные числовые фичи можно передавать открыто, используя смешанный пайплайн. Это резко сократит время вычислений и сохранит высокий уровень приватности. А канал всё равно защищён TLS. Компромисс, но в 2026-м он оправдан.

Подписаться на канал