Knative es ideal para la inference de modelos de IA. Gestiona los picos de tráfico mediante auto scaling, reduce los pods a cero cuando están inactivos y permite asignar recursos de GPU de forma flexible entre las cargas de trabajo. Esta guía describe las prácticas de configuración para cada capa de un servicio de inference basado en Knative: carga del modelo, concurrencia, auto scaling, uso compartido de GPU, probes y estrategias de despliegue.
Aceleración del despliegue de modelos
Los archivos de los modelos de IA son muy grandes. Empaquetarlos dentro de imágenes de contenedor genera dos problemas: las imágenes se vuelven demasiado pesadas para descargarse con rapidez y las versiones del modelo quedan ligadas a las versiones de la imagen. En su lugar, almacene los archivos del modelo en Object Storage Service (OSS) o File Storage NAS (NAS). Después, monte el almacenamiento en los pods de su Knative Service mediante una persistent volume claim (PVC).
Para acelerar aún más la carga del modelo, utilice Fluid. Se trata de un motor distribuido de orquestación y aceleración de conjuntos de datos que carga modelos de lenguaje grandes en segundos gracias al almacenamiento de datos en caché sobre discos SSD locales.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Knative desplegado en su clúster. Para obtener más información, consulte Deploy and manage Knative components.
El componente ack-fluid instalado. Consulte Deploy the cloud-native AI suite.
Un bucket de OSS creado. Consulte Create buckets.
Paso 1: Definir un Dataset
Cree un custom resource (CR) de tipo Dataset y otro de tipo JindoRuntime. Con ellos declarará la ubicación del modelo en OSS y configurará la caché en SSD.
apiVersion: v1
kind: Secret
metadata:
name: access-key
stringData:
fs.oss.accessKeyId: your_ak_id # Replace with your AccessKey ID.
fs.oss.accessKeySecret: your_ak_skrt # Replace with your AccessKey secret.
---
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: oss-data
spec:
mounts:
- mountPoint: "oss://{Bucket}/{path-to-model}" # Replace with your OSS bucket and model path.
name: xxx
path: "{path-to-model}" # Replace with the model path to load.
options:
fs.oss.endpoint: "oss-cn-beijing.aliyuncs.com" # Replace with your OSS bucket endpoint.
encryptOptions:
- name: fs.oss.accessKeyId
valueFrom:
secretKeyRef:
name: access-key
key: fs.oss.accessKeyId
- name: fs.oss.accessKeySecret
valueFrom:
secretKeyRef:
name: access-key
key: fs.oss.accessKeySecret
accessModes:
- ReadOnlyMany
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
name: oss-data
spec:
replicas: 2
tieredstore:
levels:
- mediumtype: SSD
volumeType: emptyDir
path: /mnt/ssd0/cache
quota: 100Gi
high: "0.95"
low: "0.7"
fuse:
properties:
fs.jindofsx.data.cache.enable: "true"
args:
- -okernel_cache
- -oro
- -oattr_timeout=7200
- -oentry_timeout=7200
- -ometrics_port=9089
cleanPolicy: OnDemand
Paso 2: Montar la PVC
Después de aplicar el CR Dataset y el CR JindoRuntime, el sistema crea automáticamente una PVC con el mismo nombre que el Dataset. Monte esta PVC en su Knative Service para que el modelo almacenado en caché esté disponible dentro del contenedor.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: sd-backend
spec:
template:
spec:
containers:
- image: <YOUR-IMAGE> # Replace with your container image name.
name: image-name
ports:
- containerPort: xxx
protocol: TCP
volumeMounts:
- mountPath: /data/models # The path where the model is loaded inside the container.
name: data-volume
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: oss-data # Must match the Dataset name.
Para obtener más información, consulte Use JindoFS to accelerate access to OSS y Use EFC to accelerate access to NAS file systems.
Paso 3: Acelerar la descarga de imágenes con cachés de imágenes
Las imágenes de contenedor para la inference de IA son grandes porque incluyen CUDA, PyTorch-GPU y otras dependencias. Cuando Knative escala horizontalmente los pods en instancias de contenedor elásticas, una descarga lenta de imágenes retrasa el inicio. Utilice ImageCache para compilar previamente una instantánea en caché de la imagen. Así, los pods iniciarán en cuestión de segundos.
apiVersion: eci.alibabacloud.com/v1
kind: ImageCache
metadata:
name: imagecache-ai-model
annotations:
k8s.aliyun.com/eci-image-cache: "true" # Enable cache reuse.
spec:
images:
- <YOUR-IMAGE>
imageCacheSize:
25 # Cache size in GiB.
retentionDays:
7 # Number of days to retain the cache.
Para obtener más información, consulte Use ImageCache to accelerate the creation of elastic container instances.
Apagado controlado de pods
Si una aplicación utiliza HTTP probing, sus pods entran en estado Not Ready tras recibir la señal SIGTERM. De este modo, ninguna solicitud nueva se enruta hacia ellos. Sin embargo, el queue-proxy de Knative puede seguir reenviando solicitudes en curso durante un breve periodo después de la señal SIGTERM. Establezca timeoutSeconds en 1.2 veces el tiempo máximo de espera de sus solicitudes para darles oportunidad de completarse.
Por ejemplo, si la solicitud más larga tarda 10 segundos, establezca timeoutSeconds en 12:
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
spec:
timeoutSeconds: 12
Configuración de la concurrencia
Los parámetros de concurrencia determinan cuántas solicitudes procesa un pod de manera simultánea. Un ajuste correcto mejora el rendimiento y evita la sobrecarga.
Límite estricto de concurrencia (containerConcurrency): impone un tope obligatorio. Las solicitudes que superan este límite se colocan en una cola y esperan capacidad disponible.
Utilice un límite estricto solo cuando su aplicación tenga un tope absoluto de concurrencia segura. Un límite bajo reduce el rendimiento, aumenta la latencia y puede provocar arranques en frío adicionales.
Límite flexible de concurrencia (autoscaling.knative.dev/target): define un objetivo no estricto. Los picos de tráfico pueden superarlo temporalmente. Es la opción predeterminada más segura para la mayoría de las cargas de trabajo de inference.
Uso objetivo (autoscaling.knative.dev/target-utilization-percentage): controla qué tan cerca del límite intenta mantenerse Knative. Establézcalo próximo al 100 % para aprovechar al máximo los pods antes de activar el escalado vertical.
Para obtener más información, consulte Configure the soft concurrency limit.
Auto scaling
Antes de ajustar el auto scaling, mida el tiempo de inicio de sus pods. Este valor determina qué parámetros son más relevantes.
Para consultar la referencia completa de parámetros, visite Enable auto scaling to withstand traffic fluctuations.
Modos de escalado
El autoscaler de Knative opera en dos modos:
Modo estable: toma decisiones de escalado con base en el tráfico promediado durante la ventana estable. Resulta adecuado para tráfico normal y predecible.
Modo pánico: reacciona más rápido mediante una ventana más corta para absorber picos repentinos de tráfico. La ventana de pánico representa un porcentaje de la ventana estable.
Ventana estable
Configure la ventana estable como mínimo al doble del tiempo promedio de inicio de sus pods. Una ventana más corta que dicho tiempo provoca que el autoscaler calcule menos pods de los necesarios, ya que los pods recién iniciados todavía no se contabilizan.
|
Parámetro |
Clave global |
Anotación por revisión |
Valor predeterminado |
|
Ventana estable |
|
|
|
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/window: "40s"
Ventana de pánico
La ventana de pánico corresponde a un porcentaje de la ventana estable.
|
Parámetro |
Clave global |
Anotación por revisión |
Rango válido |
Valor predeterminado |
|
Porcentaje de la ventana de pánico |
|
|
|
|
Una ventana de pánico corta puede generar una creación excesiva de pods cuando los tiempos de inicio son largos. Si la ventana estable es de 30 segundos y la ventana de pánico del 10 %, el autoscaler toma decisiones con base en 3 segundos de datos. Si los pods tardan 30 segundos en iniciar, el autoscaler seguirá creándolos durante todo ese periodo, lo que producirá un excedente considerable. No reduzca la ventana de pánico hasta confirmar que los demás parámetros funcionan correctamente. Si su ventana estable equivale al doble del tiempo promedio de inicio de los pods, configure la ventana de pánico en 50 % como punto de partida seguro.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/panic-window-percentage: "20.0"
Umbral del modo pánico
El umbral de pánico es la proporción entre el tráfico entrante y la capacidad actual del servicio en la que se activa el modo pánico.
|
Parámetro |
Clave global |
Anotación por revisión |
Rango válido |
Valor predeterminado |
|
Porcentaje del umbral de pánico |
|
|
|
|
Comience con el valor predeterminado (200 %) y ajústelo tras observar sus patrones de tráfico y la tolerancia de latencia.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/panic-threshold-percentage: "150.0"
Velocidades de escalado ascendente y descendente
Los valores predeterminados funcionan bien en la mayoría de los escenarios. Pruebe cualquier cambio en un entorno de staging antes de aplicarlo en producción.
Velocidad de escalado ascendente: controla la rapidez con la que se agregan pods. Auméntela si el inicio de los pods es lento, ya que los nuevos pods deben esperar a que se asignen los recursos.
apiVersion: v1
kind: ConfigMap
metadata:
name: config-autoscaler
namespace: knative-serving
data:
max-scale-up-rate: "500.0"
Velocidad de escalado descendente: establézcala como mínimo en el tiempo promedio de inicio de los pods. Esto evita reducciones agresivas que desencadenen de inmediato un nuevo escalado ascendente. El valor es una proporción: 4.0 significa que la cantidad de pods puede disminuir hasta una cuarta parte de la cifra actual por cada ciclo de escalado.
Para reducir costos, aumente la velocidad de escalado descendente y elimine los pods rápidamente cuando baje el tráfico. En servicios con pocos pods, reduzca dicha velocidad para mantener la estabilidad y evitar ciclos repetidos de escalado.
apiVersion: v1
kind: ConfigMap
metadata:
name: config-autoscaler
namespace: knative-serving
data:
max-scale-down-rate: "4.0"
Retraso de escalado descendente
El retraso de escalado descendente mantiene los pods durante un periodo fijo antes de eliminarlos. Así se evita que el autoscaler quite pods de forma agresiva y los vuelva a crear de inmediato cuando llega una nueva solicitud.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/scale-down-delay: "2m" # Keep pods for 2 minutes after scale-down decision.
Límites de escalado
Réplicas mínimas
autoscaling.knative.dev/min-scale establece el límite inferior de pods en ejecución.
|
Caso de uso |
Valor recomendado |
|
Servicio siempre disponible con poco tráfico |
|
|
Servicio expuesto a posibles picos de tráfico |
|
|
Permitir el escalado a cero durante periodos de inactividad |
|
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/min-scale: "0"
Réplicas máximas
autoscaling.knative.dev/max-scale limita la cantidad máxima de pods. Configure este valor para mantenerse dentro de su cuota de recursos.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/max-scale: "3"
Escala inicial
autoscaling.knative.dev/initial-scale define la cantidad de réplicas objetivo de una revisión durante su primer despliegue. Una vez que la revisión alcanza esa cifra y se marca como Ready, el valor deja de aplicarse. El autoscaler asume el control con base en el tráfico real, por lo que la cantidad de réplicas puede disminuir si el tráfico es bajo. Establezca este parámetro en aproximadamente 1.2 veces la cantidad actual de pods cuando ejecute despliegues con transferencia de tráfico. De este modo, la nueva revisión tendrá capacidad suficiente antes de recibir solicitudes.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/initial-scale: "3"
Uso compartido de GPU
Container Service for Kubernetes (ACK) admite el uso compartido de GPU mediante cGPU, tecnología que proporciona aislamiento de memoria de GPU entre contenedores. Para habilitar esta función en un Knative Service, configure aliyun.com/gpu-mem dentro de resources.limits.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
spec:
containerConcurrency: 1
containers:
- image: registry-vpc.cn-hangzhou.aliyuncs.com/demo-test/test:helloworld-go
name: user-container
ports:
- containerPort: 6666
name: http1
protocol: TCP
resources:
limits:
aliyun.com/gpu-mem: "3" # GPU memory in GiB allocated to this container.
Probes
Knative ejecuta probes sobre los servicios con mayor frecuencia que Kubernetes estándar para minimizar la latencia de los arranques en frío. Configure probes de liveness y de readiness en sus contenedores de inference.
Probe de liveness: supervisa el estado del contenedor. Si falla, Kubernetes reinicia el contenedor.
Probe de readiness: controla el enrutamiento del tráfico. Solo los pods que superan esta prueba reciben solicitudes.
TCP frente a HTTP:
Probe TCP: no abre el puerto de escucha hasta que todos los componentes se cargan y los contenedores están listos.
Probe HTTP: se supera únicamente cuando el endpoint devuelve una respuesta exitosa. Resulta más precisa para servicios de inference que requieren una fase de calentamiento.
Establezca periodSeconds en un valor menor que los 10 segundos predeterminados. Así reducirá el tiempo entre la disponibilidad del pod y el momento en que recibe tráfico.
Para obtener más información, consulte Configure port probing in Knative.
Escalado a cero
Cuando un Knative Service no recibe tráfico, Knative puede reducir sus pods a cero. Esto elimina los costos de recursos de los modelos inactivos.
En cargas de trabajo con muchos modelos, cree un Knative Service independiente para cada uno. Esta práctica simplifica la lógica de negocio de cada servicio y permite que cada modelo escale de forma autónoma.
Cuando un cliente accede por primera vez a un modelo inactivo, Knative escala desde cero. Para mitigar el impacto del arranque en frío, configure una reserved instance y garantice que siempre haya como mínimo un pod listo.
Para obtener más información, consulte Configure a reserved instance.
Despliegues canary
Knative mantiene en ejecución la revisión anterior hasta que la nueva está lista. De este modo garantiza la continuidad durante los despliegues.
Controle la división del tráfico mediante el campo percent, cuyo rango válido va del 10 % al 100 %. Establézcalo en 100 % para migrar por completo a la nueva revisión y retirar la anterior de inmediato.
Cuando los recursos sean limitados —por ejemplo, 500 pods en ejecución con solo 300 adicionales disponibles—, utilice un porcentaje de tráfico bajo para controlar la velocidad a la que se reduce la revisión anterior. Un porcentaje demasiado alto en esta situación puede hacer que la revisión antigua disminuya más rápido de lo que crece la nueva, lo que dejaría capacidad insuficiente.
Para obtener más información, consulte Perform a canary release based on traffic splitting for a Knative Service.
Ubicación conjunta de instancias ECS e instancias de contenedor elásticas
Configure ResourcePolicies para combinar instancias de Elastic Compute Service (ECS) con instancias de contenedor elásticas. Las instancias ECS operan durante el tráfico normal, mientras que las instancias de contenedor elásticas absorben los picos.
Escalado ascendente: Knative programa los pods primero en instancias ECS. Cuando los pods superan el límite predefinido o se agota la capacidad de ECS, los nuevos pods se asignan a instancias de contenedor elásticas.
Escalado descendente: se eliminan primero los pods alojados en instancias de contenedor elásticas.
Para obtener más información, consulte Colocate ECS instances and elastic container instances in Knative.