Instalación y Configuración de TensorFlow Serving
TensorFlow Serving es el sistema de producción oficial de Google para servir modelos TensorFlow con alta eficiencia, soporte para versionado de modelos y APIs REST y gRPC listas para producción. A diferencia de servir modelos con Flask o FastAPI, TensorFlow Serving gestiona automáticamente el ciclo de vida de los modelos, la carga bajo demanda y el balanceo entre versiones. Esta guía cubre la instalación mediante Docker y nativa, la configuración de modelos, ambas APIs y las técnicas de optimización de rendimiento.
Requisitos Previos
- Servidor Linux (Ubuntu 20.04+)
- Docker instalado (para el método Docker)
- Modelo TensorFlow guardado en formato SavedModel
- Al menos 2 GB de RAM
- GPU NVIDIA con drivers y CUDA instalados (opcional)
# Verificar Docker
docker --version
# Verificar que TensorFlow puede guardar modelos en el servidor de entrenamiento
python3 -c "import tensorflow as tf; print(tf.__version__)"
Instalación con Docker
La instalación con Docker es la más sencilla y recomendada para entornos de producción.
# Descargar la imagen oficial de TensorFlow Serving
docker pull tensorflow/serving:latest
# Para soporte GPU
docker pull tensorflow/serving:latest-gpu
# Verificar la imagen descargada
docker images | grep tensorflow/serving
Ejecutar con un modelo de ejemplo
# Descargar el modelo de ejemplo Half Plus Two
mkdir -p /tmp/tfserving
git clone https://github.com/tensorflow/serving /tmp/tfserving-repo
# Directorio del modelo de ejemplo
MODELO_DIR=/tmp/tfserving-repo/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu
# Iniciar el servidor con el modelo de ejemplo
docker run -p 8501:8501 \
-v "$MODELO_DIR:/models/half_plus_two" \
-e MODEL_NAME=half_plus_two \
tensorflow/serving &
# Probar con una solicitud REST
curl -d '{"instances": [1.0, 2.0, 5.0]}' \
-X POST http://localhost:8501/v1/models/half_plus_two:predict
Instalación Nativa en Ubuntu
# Añadir el repositorio de TensorFlow Serving
echo "deb [arch=amd64] http://storage.googleapis.com/tensorflow-serving-apt stable tensorflow-model-server tensorflow-model-server-universal" | \
sudo tee /etc/apt/sources.list.d/tensorflow-serving.list
curl https://storage.googleapis.com/tensorflow-serving-apt/tensorflow-serving.release.pub.gpg | \
sudo apt-key add -
sudo apt-get update
# Instalar TensorFlow Model Server
sudo apt-get install -y tensorflow-model-server
# Verificar la instalación
tensorflow_model_server --version
Preparar el Modelo para Serving
Los modelos deben estar en formato SavedModel con una estructura de directorios específica.
#!/usr/bin/env python3
# Guardar un modelo en el formato correcto para TensorFlow Serving
import tensorflow as tf
import numpy as np
# Crear un modelo sencillo de ejemplo
modelo = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=(10,)),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
modelo.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# Entrenamiento rápido con datos de ejemplo
X = np.random.randn(1000, 10)
y = np.random.randint(0, 2, 1000)
modelo.fit(X, y, epochs=3, verbose=0)
# Guardar en el formato SavedModel para TF Serving
# La estructura debe ser: /ruta/al/modelo/NOMBRE/VERSION/
RUTA_MODELO = "/opt/tfserving/models/mi-clasificador/1"
tf.saved_model.save(modelo, RUTA_MODELO)
print(f"Modelo guardado en: {RUTA_MODELO}")
print("Estructura de archivos:")
import os
for r, d, f in os.walk(RUTA_MODELO):
nivel = r.replace(RUTA_MODELO, '').count(os.sep)
print(f"{' ' * nivel}{os.path.basename(r)}/")
for archivo in f:
print(f"{' ' * (nivel + 1)}{archivo}")
Inspeccionar la firma del modelo
# Ver las entradas y salidas del modelo guardado
saved_model_cli show \
--dir /opt/tfserving/models/mi-clasificador/1 \
--all
# Ver solo las firmas de servicio
saved_model_cli show \
--dir /opt/tfserving/models/mi-clasificador/1 \
--tag_set serve \
--signature_def serving_default
Configuración del Servidor
Configuración básica
# Crear la estructura de directorios
mkdir -p /opt/tfserving/{models,configs,logs}
# Iniciar el servidor apuntando a un único modelo
tensorflow_model_server \
--rest_api_port=8501 \
--grpc_port=8500 \
--model_name=mi-clasificador \
--model_base_path=/opt/tfserving/models/mi-clasificador
Archivo de configuración para múltiples modelos
# Crear el archivo de configuración de modelos
cat > /opt/tfserving/configs/models.config << 'EOF'
model_config_list {
config {
name: "mi-clasificador"
base_path: "/opt/tfserving/models/mi-clasificador"
model_platform: "tensorflow"
model_version_policy {
latest {
num_versions: 2
}
}
}
config {
name: "modelo-nlp"
base_path: "/opt/tfserving/models/modelo-nlp"
model_platform: "tensorflow"
model_version_policy {
specific {
versions: 3
versions: 5
}
}
}
}
EOF
# Iniciar el servidor con el archivo de configuración
tensorflow_model_server \
--rest_api_port=8501 \
--grpc_port=8500 \
--model_config_file=/opt/tfserving/configs/models.config \
--model_config_file_poll_wait_seconds=60
Configurar como servicio systemd
sudo cat > /etc/systemd/system/tfserving.service << 'EOF'
[Unit]
Description=TensorFlow Serving
After=network.target
[Service]
Type=simple
User=tfserving
Group=tfserving
ExecStart=/usr/bin/tensorflow_model_server \
--rest_api_port=8501 \
--grpc_port=8500 \
--model_config_file=/opt/tfserving/configs/models.config \
--model_config_file_poll_wait_seconds=60 \
--enable_model_warmup=true
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo useradd -r -s /bin/false tfserving
sudo chown -R tfserving:tfserving /opt/tfserving/
sudo systemctl daemon-reload
sudo systemctl enable tfserving
sudo systemctl start tfserving
API REST
# Verificar que el modelo está cargado
curl http://localhost:8501/v1/models/mi-clasificador
# Ver las versiones del modelo
curl http://localhost:8501/v1/models/mi-clasificador/versions
# Hacer una predicción (una sola instancia)
curl -s -X POST http://localhost:8501/v1/models/mi-clasificador:predict \
-H "Content-Type: application/json" \
-d '{
"instances": [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]]
}' | python3 -m json.tool
# Predicción de múltiples instancias (batch)
curl -s -X POST http://localhost:8501/v1/models/mi-clasificador:predict \
-H "Content-Type: application/json" \
-d '{
"instances": [
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0],
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
]
}'
# Predicción en una versión específica del modelo
curl -s -X POST http://localhost:8501/v1/models/mi-clasificador/versions/2:predict \
-H "Content-Type: application/json" \
-d '{"instances": [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]]}'
Cliente Python para la API REST
import requests
import numpy as np
def predecir(datos, modelo="mi-clasificador", servidor="http://localhost:8501"):
"""Enviar datos para inferencia via API REST."""
url = f"{servidor}/v1/models/{modelo}:predict"
payload = {"instances": datos.tolist()}
respuesta = requests.post(url, json=payload)
respuesta.raise_for_status()
return respuesta.json()["predictions"]
# Ejemplo de uso
datos = np.random.randn(5, 10) # 5 muestras, 10 features
predicciones = predecir(datos)
print(f"Predicciones: {predicciones}")
API gRPC
gRPC es más eficiente que REST para volúmenes altos de solicitudes.
# Instalar las dependencias para el cliente gRPC
pip install grpcio tensorflow-serving-api
#!/usr/bin/env python3
# Cliente gRPC para TensorFlow Serving
import grpc
import numpy as np
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
import tensorflow as tf
def predecir_grpc(datos, modelo="mi-clasificador", host="localhost:8500"):
"""Inferencia usando la API gRPC de TF Serving."""
# Crear el canal gRPC
canal = grpc.insecure_channel(host)
stub = prediction_service_pb2_grpc.PredictionServiceStub(canal)
# Construir la solicitud
solicitud = predict_pb2.PredictRequest()
solicitud.model_spec.name = modelo
solicitud.model_spec.signature_name = "serving_default"
# Convertir los datos a tensor proto
solicitud.inputs["dense_input"].CopyFrom(
tf.make_tensor_proto(datos, dtype=tf.float32)
)
# Enviar la solicitud con timeout
resultado = stub.Predict(solicitud, 10.0) # 10 segundos de timeout
return resultado.outputs["dense_1"].float_val
# Ejemplo de uso
datos = np.random.randn(3, 10).astype(np.float32)
predicciones = predecir_grpc(datos)
print(f"Predicciones gRPC: {list(predicciones)}")
Soporte GPU
# Usar la imagen GPU de Docker
docker run --gpus all -p 8501:8501 -p 8500:8500 \
-v /opt/tfserving/models:/models \
-e MODEL_NAME=mi-clasificador \
tensorflow/serving:latest-gpu
# Para la instalación nativa, el servidor detecta la GPU automáticamente
# si los drivers CUDA están correctamente instalados
# Limitar el uso de VRAM por modelo (en el archivo de configuración)
# Añadir al archivo models.config:
# experimental_fixed_model_config {
# tf_session_parallelism: 4
# }
Versionado y Actualización de Modelos
# Añadir una nueva versión del modelo sin reiniciar el servidor
# Crear el directorio de la versión 2
mkdir -p /opt/tfserving/models/mi-clasificador/2
# Copiar/guardar el nuevo modelo en ese directorio
# TF Serving cargará automáticamente la nueva versión
# Ver las versiones activas
curl http://localhost:8501/v1/models/mi-clasificador
# Actualización de la configuración en caliente
curl -X POST http://localhost:8501/v1/models/mi-clasificador/reload
Solución de Problemas
Error: Failed to load model
# Ver los logs del servidor
sudo journalctl -u tfserving -f
# Verificar la estructura del modelo
saved_model_cli show --dir /opt/tfserving/models/mi-clasificador/1 --all
# Verificar permisos
ls -la /opt/tfserving/models/mi-clasificador/1/
Error de dimensiones en las predicciones
# Ver la firma exacta del modelo para conocer las dimensiones esperadas
saved_model_cli show \
--dir /opt/tfserving/models/mi-clasificador/1 \
--tag_set serve \
--signature_def serving_default
Alta latencia en las predicciones
# Habilitar el batching automático
cat > /opt/tfserving/configs/batching.txt << 'EOF'
max_batch_size { value: 32 }
batch_timeout_micros { value: 10000 }
max_enqueued_batches { value: 100 }
num_batch_threads { value: 4 }
EOF
tensorflow_model_server \
--enable_batching=true \
--batching_parameters_file=/opt/tfserving/configs/batching.txt \
--model_config_file=/opt/tfserving/configs/models.config
Conclusión
TensorFlow Serving ofrece una solución robusta y de alto rendimiento para servir modelos en producción con gestión automática de versiones, APIs REST y gRPC, y soporte nativo para GPU. La combinación de archivos de configuración en caliente y el versionado automático permite actualizar los modelos sin interrupciones del servicio, convirtiéndolo en la opción preferida para sistemas de inferencia de alta disponibilidad.


