Documentazione Tecnica — Seldon Core v2
🧠 Introduzione
Questa guida tecnica descrive come servire modelli di machine learning utilizzando Seldon Core v2, compatibile con KServe e MLServer, seguendo lo standard Open Inference Protocol v2.
Il "serving" di un modello consiste nel rendere disponibile un modello di machine learning come servizio accessibile tramite API REST. Questo consente di effettuare inferenze (predizioni) in tempo reale, integrando il modello in applicazioni o pipeline di produzione. Seldon Core v2 gestisce il deployment, la scalabilità, il monitoraggio e la versione dei modelli, facilitando l'integrazione con Kubernetes.
🔗 Endpoint Principali
| Scopo | Metodo | Endpoint |
|---|---|---|
| Inferenza | POST | /v2/models/<MODEL>/infer |
| Metadata modello | GET | /v2/models/<MODEL> |
| Health check | GET | /v2/health/ready, /v2/models/<MODEL>/ready |
📦 Schema della Richiesta
{
"id": "req-1",
"inputs": [
{
"name": "input-0",
"shape": [1, 4],
"datatype": "FP32",
"data": [0.1, 0.2, 0.3, 0.4]
}
]
}
-shape: dimensione del tensore (prodotto = numero di elementi)
-datatype: tipo di dato (vedi sotto)
-data: array flat in ordine row-major
📚 Tipi di Dato Supportati
| Tipo | Descrizione | |
|---|---|---|
| InFP32/FP64 | Float | |
| INT32/64 | Interi | |
| BOOL | Booleani | |
| BYTES | Stringhe o immagini (con parameters.content_type) |
⚙️ Esempi di Richieste
🔢 Numerico
curl -X POST "https://<host>/v2/models/my-sklearn/infer" \
-H "Content-Type: application/json" \
-d '{"inputs":[
{"name":"input-0",
"shape":[1,4],
"datatype":"FP32",
"data":[5.1,3.5,1.4,0.2]
}
]
}
📝 Testo (BYTES)
curl -X POST "https://<host>/v2/models/my-nlp/infer" \
-H "Content-Type: application/json" \
-d '{"inputs":[{"name":"text","shape":[1],"datatype":"BYTES","parameters":{"content_type":"str"},"data":["hello world"]}]}'
🖼️ Immagine (base64)
curl -X POST "https://<host>/v2/models/cifar10/infer" \
-H "Content-Type: application/json" \
-d '{"inputs":[
{
"name":"image",
"shape":[1,3,32,32],
"datatype":"BYTES",
"parameters":{"content_type":"base64"},
"data":["$B64"]
}
]
}
```
📤 Output Esempio
```json
{
"model_name": "my-sklearn",
"id": "req-1",
"outputs": [
{
"name": "probabilities",
"shape": [1, 3],
"datatype": "FP32",
"data": [0.1, 0.7, 0.2]
}
]
}
✅ Checklist Rapida
shapecoerente con i datidatatypecorretto (BYTESper testo/immagini)parameters.content_typeper stringhe/base64- dimensione batch → prima dimensione (
[N, …])
📘 Tip
Puoi recuperare gli inputs attesi con:
e usare i relativi name, shape, datatype per costruire il body corretto.
LATO SVILUPPO SERVIZI
Se il servizio fa uso del tracking e del salvataggio con MlFlow basta avere alcune accortezze:
• Impostare sempre la signature con mlflow.models.infer_signature( X_train, y_train)
• Far uso di pandas dataframe in fase di addestramento così da avere l'informazione sui nomi delle feature
• Se il modello include una pipeline di trasformazione ricordarsi in fase di inferenza che la trasformazione verrà applicata direttamente, quindi non occorre trasformare i dati
📘FORMAT SKLEARN
(mlflow supporta i modelli sklearn, quindi potrebbe essere conveniente farne uso così da non aver bisogno dei seguenti passaggi)
Obiettivo: Permettere a MLServer (runtime mlserver_sklearn.SKLearnModel) di caricare il modello joblib o pkl, e pubblicare lo schema I/O su /v2/models/{name} (vecchio Model Metadata).
📁 Posizionamento
Il file model-settings.json deve essere salvato nella stessa cartella del file modello (model.joblib) e caricato su MinIO.
Quando Seldon la scarica nel Pod, MLServer trova entrambi i file nello stesso percorso.
📄 Esempio Campi fondamentali:
{
"name": "model-<MODEL_ID>",
"implementation": "mlserver_sklearn.SKLearnModel",
"parameters": {
"uri": "./model.joblib",
"content_type": "np",
"task_type": "classification",
"feature_names": ["feature1", "feature2"]
},
"inputs": [
{
"name": "features",
"datatype": "FP32",
"shape": [-1, 27]
}
],
"outputs": [
{
"name": "label",
"datatype": "INT64",
"shape": [-1, 1]
}
]
}
📘 Descrizione dei Campi Principali
| Campo | Target | Descrizione |
|---|---|---|
| name | nome del modello | deve corrispondere a quello usato da Seldon (es. model-123) |
| implementation | runtime MLServer da usare | per modelli sklearn → mlserver_sklearn.SKLearnModel |
| parameters.uri | percorso locale del file modello | es. ./model.joblib |
| parameters.content_type | tipo iput accettato | np: tensore numerico (JSON) o pd: formato colonnare (stringhe o misti) o str: lista di stringhe |
| parameters.task_type | tipo di task (solo informativo) | regression, classification, clustering |
| parameters.feature_names | opzionale | utile per modelli con colonne stringa o miste |
| inputs | descrive gli ingressi | (nome, tipo e shape) |
| outputs | descrive gli output | (nome, tipo e shape) |
📘 Esempi di Input Caso A — Tabellare numerico
"parameters": { "uri": "./model.joblib", "content_type": "np" },
"inputs": [
{ "name": "features", "datatype": "FP32", "shape": [-1, 27] }
]
Caso B - Pipeline con colonne stringa o miste
"parameters": {
"uri": "./model.joblib",
"content_type": "pd",
"feature_names": ["city","gender","segment"]
},
"inputs": [
{ "name": "city", "datatype": "BYTES", "shape": [-1] },
{ "name": "gender", "datatype": "BYTES", "shape": [-1] },
{ "name": "segment", "datatype": "BYTES", "shape": [-1] }
]
Caso C - Pipeline che si aspetta testo grezzo (una sola feature stringa)
"parameters": { "uri": "./model.joblib", "content_type": "str" },
"inputs": [
{ "name": "text", "datatype": "BYTES", "shape": [-1] }
]
📘 Linee guida per outputs:
Gli outputs descrivono il formato dei risultati che il modello produce.
Ogni elemento in "outputs" è definito da:
• name: nome logico dell’output (pred, label, proba, scores); non ha alcun effetto sull'inferenza, serve solo a "formattare" la risposta di seldon
• datatype: tipo del dato restituito (FP32, INT64)
• shape: dimensione del tensore, con -1 per il batch
I campi dichiarati nella sezione "outputs" del file servono solo a documentare lo schema, ma non influenzano i valori effettivamente calcolati.
Se si dichiara output che il modello non produce, non compaiono nella risposta di /infer, ma restano visibili nel metadata.
Usare nomi coerenti con il tipo di modello
• (pred, label)
• impostare shape coerente: [-1,1] per valori scalari, [-1,K] per vettori di K classi