Ваши данные никто не должен видеть. Даже модель.
Звучит параноидально? А теперь представьте: вы передаете медицинские снимки облачному 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:
- Клиент (ваше приложение) генерирует пару ключей (секретный + вычислений).
- Клиент шифрует входные данные (числа или one-hot векторы) с помощью открытого ключа.
- Зашифрованный тензор отправляется в SageMaker Endpoint через HTTPS.
- Контейнер с FHE-моделью выполняет вычисления на зашифрованных данных (без расшифровки).
- Зашифрованный результат возвращается клиенту.
- Клиент расшифровывает результат секретным ключом.
Ключевой момент: модель должна быть скомпилирована в 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, ни кто-либо еще не знает, какие данные вы отправили и что предсказала модель. Только вы.
Типичные грабли и как их избежать
- Таймауты. 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-м он оправдан.