TensorFlowSeniorExperience

Какие ошибки делают команды, когда переносят notebook/prototype-подход на production data/AI pipeline?

Главные ошибки при переносе ML в production: preprocessing только в памяти ноутбука (не сохранён как артефакт), отсутствие версионирования данных/моделей (DVC, MLflow), нет валидации входных данных, жёстко заданные пути, и отсутствие мониторинга drift после деплоя.

Типичные ошибки при переносе ML из ноутбука в production

Переход от Jupyter-ноутбука к production ML-пайплайну — один из самых сложных шагов в ML-инженерии. Команды систематически совершают одни и те же ошибки независимо от выбора фреймворка (TensorFlow, PyTorch, sklearn).

1. Preprocessing вшит в ноутбук, а не в пайплайн

В ноутбуке преобразования данных делаются «по месту» через переменные в памяти. В production входные данные поступают в сыром виде, и воспроизвести те же преобразования без артефактов (fitted scaler, vocabulary, encoders) невозможно.

# ПРОБЛЕМА: preprocessing только в памяти ноутбука
X_scaled = (X - X.mean()) / X.std()  # mean/std не сохранены!

# РЕШЕНИЕ: TF preprocessing layers сохраняются вместе с моделью
import tensorflow as tf

normalization = tf.keras.layers.Normalization()
normalization.adapt(X_train)

model = tf.keras.Sequential([
    normalization,  # preprocessing внутри модели
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(1),
])
model.save('model.keras')  # normalization stats сохранены!

2. Отсутствие версионирования данных и моделей

В ноутбуке модель просто сохраняется как файл. В production невозможно воспроизвести обучение без знания точной версии датасета, гиперпараметров и кода. Инструменты: DVC для данных, MLflow или W&B для экспериментов.

# DVC для версионирования датасета
dvc add data/train.csv
dvc push

# MLflow для трекинга экспериментов
import mlflow
import mlflow.tensorflow

with mlflow.start_run():
    mlflow.log_param('learning_rate', 0.001)
    mlflow.log_param('epochs', 50)
    mlflow.log_param('batch_size', 32)

    model.fit(X_train, y_train, epochs=50, batch_size=32)

    mlflow.log_metric('val_auc', val_auc)
    mlflow.tensorflow.log_model(model, 'model')

3. Отсутствие тестов на данные и модель

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

import great_expectations as ge
import tensorflow_data_validation as tfdv

# Валидация входных данных перед обучением
df = ge.from_pandas(raw_data)
df.expect_column_values_to_not_be_null('feature_age')
df.expect_column_values_to_be_between('feature_age', min_value=0, max_value=120)
df.expect_column_values_to_be_in_set('category', ['A', 'B', 'C'])

result = df.validate()
assert result['success'], f"Data validation failed: {result}"

4. Жёстко заданные пути и конфигурация

# ПРОБЛЕМА
data_path = '/Users/john/Desktop/my_project/data.csv'  # локальный путь
model_path = 'model.h5'

# РЕШЕНИЕ: конфиг через переменные окружения или Hydra/Pydantic
import os
from pydantic_settings import BaseSettings

class MLConfig(BaseSettings):
    data_path: str
    model_output_path: str
    learning_rate: float = 0.001
    batch_size: int = 32
    max_epochs: int = 100

    class Config:
        env_prefix = 'ML_'

config = MLConfig()

5. Нет мониторинга после деплоя

Команды деплоят модель и считают, что работа сделана. Без мониторинга data drift и деградации метрик модель тихо ухудшается неделями.

Подводные камни

  • Training-serving skew: preprocessing в ноутбуке и в serving-коде расходятся — используйте TF preprocessing layers или ONNX, чтобы preprocessing был частью артефакта модели.
  • Ноутбуки не тестируемы — код в ячейках не покрывается unit-тестами, переход на модули с pytest обязателен для production.
  • Global state в ноутбуках (переменные, импорты) не воспроизводим при перезапуске — использование Restart & Run All должно давать идентичный результат.
  • Отсутствие seed для воспроизводимости: tf.random.set_seed(42) и numpy.random.seed(42) нужны явно.
  • Большие датасеты не помещаются в RAM на ноутбуке — переход на tf.data.Dataset с .cache() и .prefetch() необходим заранее.
  • Зависимости ноутбука неявны — requirements.txt или pyproject.toml с точными версиями обязателен.
  • Жёстко заданные размеры входных тензоров ломаются при изменении batch size или добавлении признаков — используйте None для динамических измерений.
  • Отсутствие graceful degradation: если модель недоступна, система должна уметь работать с fallback-логикой, а не падать с 500.

What hurts your answer

  • Говорить только о запуске TensorFlow, но не об эксплуатации
  • Не упоминать observability, обновления, безопасность и rollback
  • Описывать риски абстрактно, без способов их снижать

What they're listening for

  • Видит production-риски TensorFlow
  • Говорит про monitoring, rollout, rollback и безопасность
  • Умеет ранжировать риски по вероятности и влиянию

Related topics