Le processeur TorchEasyRec intégré à EAS déploie les modèles de recommandation entraînés avec TorchEasyRec ou PyTorch en tant que services de scoring avec ingénierie des fonctionnalités intégrée. Le processeur optimise conjointement l'ingénierie des fonctionnalités et le modèle PyTorch pour offrir des services de scoring haute performance. Cette rubrique explique comment déployer et appeler un service de modèle TorchEasyRec.
Contexte
Le diagramme suivant illustre l'architecture d'un moteur de recommandation basé sur le processeur TorchEasyRec.
Le processeur TorchEasyRec se compose des modules suivants :
Item Feature Cache : met en cache les fonctionnalités côté article issues de FeatureStore en mémoire afin de réduire la charge réseau, d'alléger la charge sur FeatureStore et d'améliorer les performances du service d'inférence. Lorsque les fonctionnalités côté article incluent des données en temps réel, FeatureStore gère leur synchronisation.
feature generator (FG) : définit les transformations de fonctionnalités dans un fichier de configuration, en s'appuyant sur une base de code C++ unifiée pour garantir une logique cohérente entre le traitement hors ligne et en ligne des fonctionnalités.
TorchModel : modèle PyTorch entraîné avec TorchEasyRec ou PyTorch et exporté sous forme de ScriptedModel.
Limites
La prise en charge est limitée aux modèles g6, g7 et g8 de la famille d'instances à usage général, ainsi qu'aux modèles GPU tels que T4 et A10. Pour plus d'informations, consultez la page relative à la famille d'instances à usage général (série g). Si vous déployez un service GPU, assurez-vous que la version du pilote CUDA est 535 ou ultérieure.
Historique des versions
Le processeur TorchEasyRec est en développement actif. Nous vous recommandons d'utiliser la dernière version pour déployer votre service d'inférence, car elle offre davantage de fonctionnalités et de meilleures performances d'inférence. Les versions publiées sont les suivantes :
Processeur | Date | Version Torch | Version FG | Mises à jour |
easyrec-torch-0.1 | 2024-09-10 | 2.4 | 0.2.9 |
|
easyrec-torch-0.2 | 2024-09-30 | 2.4 | 0.2.9 |
|
easyrec-torch-0.3 | 2024-10-14 | 2.4 | 0.2.9 |
|
easyrec-torch-0.4 | 2024-10-28 | 2.4 | 0.3.1 |
|
easyrec-torch-0.5 | 2024-11-14 | 2.4 | 0.3.1 |
|
easyrec-torch-0.6 | 2024-11-18 | 2.4 | 0.3.6 |
|
easyrec-torch-0.7 | 2024-12-06 | 2.5 | 0.3.9 |
|
easyrec-torch-0.8 | 2024-12-25 | 2.5 | 0.3.9 |
|
easyrec-torch-0.9 | 2025-01-15 | 2.5 | 0.4.1 |
|
easyrec-torch-1.0 | 2025-02-06 | 2.5 | 0.4.2 |
|
easyrec-torch-1.1 | 2025-04-23 | 2.5 | 0.5.9 |
|
easyrec-torch-1.2 | 2025-05-12 | 2.5 | 0.6.0 |
|
easyrec-torch-1.3 | 2025-05-29 | 2.5 | 0.6.5 |
|
easyrec-torch-1.4 | 2025-07-15 | 2.5 | 0.6.9 |
|
easyrec-torch-1.5 | 2025-09-18 | 2.5 | 0.7.3 |
|
easyrec-torch-1.6 | 2025-10-21 | 2.5 | 0.7.4 |
|
easyrec-torch-1.7 | 2025-11-04 | 2.5 | 0.7.4 |
|
easyrec-torch-1.8 | 2025-12-01 | 2.5 | 0.7.4 |
|
easyrec-torch-1.9 | 2026-01-09 | 2.5 | 1.0.0 |
|
easyrec-torch-1.10 | 2026-01-23 | 2.5 | 1.0.1 |
|
easyrec-torch-1.11 | 2026-02-10 | 2.5 | 1.0.1 |
|
easyrec-torch-1.12 | 2026-03-13 | 2.5 | 1.0.1 |
|
Notes sur la version 2.0 et les versions ultérieures
| ||||
easyrec-torch-2.0 | 2026-03-17 | 2.8 | 1.0.1 |
|
easyrec-torch-2.1 | 2026-04-09 | 2.8 | 1.0.2 |
|
easyrec-torch-2.2 | 2026-04-29 | 2.8 | 1.0.5 |
|
easyrec-torch-2.3 | 2026-06-08 | 2.11 | 1.0.5 |
|
Étape 1 : Déployer un service
-
Préparez le fichier de configuration de service
torcheasyrec.json.Vous devez spécifier le Type de processeur comme easyrec-torch-{version} et sélectionner une valeur pour {version} dans l'historique des versions. Voici un exemple de fichier de configuration JSON :
Exemple avec FG (fg_mode='normal')
{ "metadata": { "instance": 1, "name": "alirec_rank_with_fg", "rpc": { "enable_jemalloc": 1, "max_queue_size": 256, "worker_threads": 16 } }, "cloud": { "computing": { "instance_type": "ecs.gn6i-c16g1.4xlarge" } }, "model_config": { "fg_mode": "normal", "fg_threads": 8, "region": "YOUR_REGION", "fs_project": "YOUR_FS_PROJECT", "fs_model": "YOUR_FS_MODEL", "fs_entity": "item", "load_feature_from_offlinestore": true, "access_key_id":"YOUR_ACCESS_KEY_ID", "access_key_secret":"YOUR_ACCESS_KEY_SECRET" }, "storage": [ { "mount_path": "/home/admin/docker_ml/workspace/model/", "oss": { "path": "oss://xxx/xxx/export", "readOnly": false }, "properties": { "resource_type": "code" } } ], "processor":"easyrec-torch-1.12" }Exemple sans FG (fg_mode='bypass')
{ "metadata": { "instance": 1, "name": "alirec_rank_no_fg", "rpc": { "enable_jemalloc": 1, "max_queue_size": 256, "worker_threads": 16 } }, "cloud": { "computing": { "instance_type": "ecs.gn6i-c16g1.4xlarge" } }, "model_config": { "fg_mode": "bypass" }, "storage": [ { "mount_path": "/home/admin/docker_ml/workspace/model/", "oss": { "path": "oss://xxx/xxx/export", "readOnly": false }, "properties": { "resource_type": "code" } } ], "processor":"easyrec-torch-1.12" }Pour les autres paramètres, consultez la rubrique Déploiement JSON.
Paramètre
Obligatoire
Description
Exemple
processor
Oui
Le processeur TorchEasyRec.
"processor":"easyrec-torch-1.12"
path
Oui
Le chemin OSS monté sur le service pour stocker les fichiers de modèle.
"path": "oss://examplebucket/xxx/export"
fg_mode
Non
Spécifie le mode d'ingénierie des fonctionnalités (FG). Valeurs valides :
bypass (par défaut) : Désactive l'ingénierie des fonctionnalités (FG). Seul le modèle Torch est déployé.
Utilisez ce mode pour le traitement personnalisé des fonctionnalités.
Dans ce mode, le processeur ne requiert pas les paramètres d'accès à FeatureStore.
normal : Active la FG. Ce mode est généralement utilisé avec TorchEasyRec pour l'entraînement des modèles.
"fg_mode": "normal"
fg_threads
Non
Le nombre de threads simultanés pour l'exécution de la FG par requête.
"fg_threads": 15
outputs
Non
Les noms des variables de sortie de la prédiction du modèle Torch, telles que
probs_ctr. Séparez plusieurs noms par des virgules (,). Si ce paramètre n'est pas spécifié, le service renvoie toutes les variables."outputs":"probs_ctr,probs_cvr"
item_empty_score
Non
La note par défaut à renvoyer lorsqu'un ID d'élément n'existe pas. Valeur par défaut : 0.
"item_empty_score": -1
Paramètres de rappel vectoriel du processeur
faiss_neigh_num
Non
Le nombre d'éléments à récupérer pour le rappel vectoriel FAISS. Le service privilégie la valeur du champ
faiss_neigh_numdans le corps de la requête. Si ce champ n'est pas fourni, il utilise la valeur du paramètrefaiss_neigh_numdans la sectionmodel_config. La valeur par défaut est 1."faiss_neigh_num": 200
faiss_nprobe
Non
Le paramètre
nprobespécifie le nombre de clusters à rechercher lors de la récupération. Dans FAISS, un index de fichier inversé divise les données en clusters plus petits et maintient une liste inversée pour chacun. Une valeurnprobeplus élevée améliore généralement la précision du rappel au prix d'une augmentation du calcul et du temps de recherche, tandis qu'une valeur plus faible réduit la précision mais accélère la recherche. La valeur par défaut est 800."faiss_nprobe" : 700
Paramètres du processeur pour l'accès à FeatureStore
fs_project
Non
Le nom de votre projet FeatureStore. Ce paramètre est requis lors de l'utilisation de FeatureStore. Pour plus d'informations, consultez Configurer un projet FeatureStore.
"fs_project": "fs_demo"
fs_model
Non
Le nom du modèle de fonctionnalité dans FeatureStore.
"fs_model": "fs_rank_v1"
fs_entity
Non
Le nom de l'entité dans FeatureStore.
"fs_entity": "item"
region
Non
La région où se trouve votre projet FeatureStore. Par exemple, spécifiez
cn-beijingpour la région Chine (Pékin). Pour la liste des régions prises en charge et de leurs endpoints, consultez Endpoints."region": "cn-beijing"
access_key_id
Non
L'AccessKey ID pour accéder à FeatureStore.
"access_key_id": "xxxxx"
access_key_secret
Non
L'AccessKey Secret pour accéder à FeatureStore.
"access_key_secret": "xxxxx"
load_feature_from_offlinestore
Non
Spécifie s'il faut charger les fonctionnalités hors ligne directement depuis l'OfflineStore de FeatureStore. Valeurs valides :
True : Charge les données depuis l'OfflineStore de FeatureStore.
False (par défaut) : Charge les données depuis l'OnlineStore de FeatureStore.
"load_feature_from_offlinestore": True
featuredb_username
Non
Le nom d'utilisateur pour FeatureDB.
"featuredb_username":"xxx"
featuredb_password
Non
Le mot de passe pour FeatureDB.
"featuredb_passwd":"xxx"
Paramètres pour l'expansion automatique des fonctionnalités (input_tile)
INPUT_TILE
Non
Active l'expansion automatique des fonctionnalités pour optimiser les performances. Pour les fonctionnalités qui partagent la même valeur pour tous les éléments d'une seule requête, comme un
user_id, vous pouvez envoyer la valeur une seule fois. Cela permet de réduire la taille de la charge utile de la requête, la latence réseau et le temps de calcul.Cette fonctionnalité doit être utilisée en mode
normalet avec un modèle entraîné avec TorchEasyRec. La variable d'environnement correspondante doit également être définie lors de l'exportation du modèle. Par défaut, le système lit la valeurINPUT_TILEà partir du fichiermodel_acc.jsondans le répertoire du modèle exporté. Si ce fichier est absent, le système lit la valeur à partir de la variable d'environnement.Lorsque cette fonctionnalité est activée :
Si la variable d'environnement est définie sur 2, la FG pour les fonctionnalités côté utilisateur est calculée une seule fois.
Si la variable d'environnement est définie sur 3, la FG pour les fonctionnalités côté utilisateur est calculée une seule fois. Le système calcule séparément les embeddings pour les fonctionnalités utilisateur et élément, et l'embedding côté utilisateur est calculé une seule fois. Ce paramètre est idéal pour les scénarios comportant de nombreuses fonctionnalités côté utilisateur.
"processor_envs":
[
{
"name": "INPUT_TILE",
"value": "2"
}
]
NO_GRAD_GUARD
Non
Désactive le calcul des gradients pendant l'inférence. Cela arrête le suivi des opérations et empêche la construction d'un graphe de calcul.
RemarqueLa définition de ce paramètre sur
1peut entraîner des problèmes d'incompatibilité avec certains modèles. Si le service se bloque lors d'une deuxième exécution d'inférence, vous pouvez résoudre le problème en définissant la variable d'environnementPYTORCH_TENSOREXPR_FALLBACK=2. Cela contourne l'étape de compilation tout en conservant certaines capacités d'optimisation du graphe."processor_envs":
[
{
"name": "NO_GRAD_GUARD",
"value": "1"
}
]
Paramètres de préchauffage du modèle
warmup_data_path
Non
Active la fonctionnalité de préchauffage du modèle et spécifie le chemin pour enregistrer les fichiers de préchauffage. Pour persister les fichiers de préchauffage, vous devez monter un chemin OSS vers cet emplacement dans la configuration
storage."warmup_data_path": "/warmup"
warmup_cnt_per_file
Non
Le nombre de fois où exécuter le processus de préchauffage pour chaque fichier Protobuf. Une valeur plus élevée garantit un préchauffage plus complet mais augmente le temps de démarrage. Valeur par défaut : 20.
"warmup_cnt_per_file": 20,
warmup_pb_files_count
Non
Le nombre de requêtes en ligne à enregistrer sous forme de fichiers Protobuf pour le prochain démarrage du service. Les fichiers sont utilisés pour le préchauffage du modèle et sont enregistrés dans le chemin spécifié par
warmup_data_path. Valeur par défaut : 64."warmup_pb_files_count": 64
Journalisation et enregistrement des requêtes lentes
long_request_threshold
Non
Le seuil de temps en millisecondes (ms) pour identifier une requête lente. Si le temps de traitement d'une requête dépasse ce seuil, le système enregistre automatiquement le temps d'exécution de chaque étape. Valeur par défaut : 200.
"long_request_threshold": 200
save_long_request
Non
Spécifie s'il faut enregistrer les requêtes dépassant le
long_request_thresholdsous forme de fichiers Protobuf. Si la valeur est définie surtrue, les fichiers sont enregistrés dans le répertoiretorch_reqsous le répertoire du modèle. Valeur par défaut :false."save_long_request": true
Enregistrement des requêtes brutes et des fonctionnalités des éléments sur OSS
request_log_path
Non
Le chemin disque pour enregistrer les fichiers Protobuf. Vous devez monter un chemin OSS vers cet emplacement dans la configuration du service.
"request_log_path": "/online_log_pb"
background_feature_thread_num
Non
Le nombre de threads d'arrière-plan dédiés à l'écriture de fichiers sur le disque. Si la charge d'écriture sur le disque est importante, vous pouvez augmenter cette valeur pour accélérer le processus d'enregistrement. Valeur par défaut : 4.
"background_feature_thread_num": 8
Configuration des données de pass-through
pass_through_data
Non
Spécifie les données à transmettre dans la réponse. Cela est utile pour transmettre des informations aux services en aval. La valeur doit être un objet JSON.
"pass_through_data": {"model_version": "20260513"}
-
Déployez le service de modèle TorchEasyRec en utilisant l'une des méthodes suivantes :
JSON (recommandé)
Suivez ces étapes :
Connectez-vous à la PAI console. Sélectionnez une région en haut de la page. Ensuite, sélectionnez l'espace de travail souhaité et cliquez sur Elastic Algorithm Service (EAS).
Sur la page Elastic Algorithm Service (EAS), cliquez sur Deploy Service. Dans la section Custom Model Deployment, cliquez sur JSON Deployment.
Dans l'éditeur JSON, collez votre configuration JSON, puis cliquez sur Deploy.
CLI eascmd
Téléchargez et authentifiez le client. Les étapes suivantes utilisent la version Windows 64 bits à titre d'exemple.
-
Depuis le répertoire contenant votre fichier JSON, exécutez la commande suivante pour créer un service. Pour plus d'informations sur la commande, consultez la rubrique Référence des commandes.
eascmdwin64.exe create <service.json>Remplacez <service.json> par le nom de votre fichier JSON, par exemple
torcheasyrec.json.
Étape 2 : Appeler un service
Après avoir déployé le service de modèle TorchEasyRec, suivez ces étapes pour afficher les informations d'appel du service :
Connectez-vous à la PAI console, sélectionnez la région en haut de la page et l'espace de travail à droite, puis cliquez sur Go to EAS.
Cliquez sur Invocation Information dans la colonne Service Type pour le service cible afin de voir l'endpoint du service et le jeton.

Le service de modèle TorchEasyRec utilise Protobuf comme format d'entrée/sortie. Il existe deux méthodes d'appel, selon que la FG est activée ou non :
Utilisation de FG (fg_mode='normal')
Vous pouvez appeler le service à l'aide de l'une des méthodes suivantes :
EAS Java SDK
Avant d'exécuter le code, configurez votre environnement Maven. Pour plus d'informations, consultez les instructions d'utilisation du SDK Java dans la rubrique Instructions d'utilisation du SDK Java. Pour obtenir la dernière version du SDK Java, consultez le dépôt https://github.com/pai-eas/eas-java-sdk. L'exemple de code suivant montre comment envoyer une requête au service alirec_rank_with_fg.
package com.aliyun.openservices.eas.predict;
import com.aliyun.openservices.eas.predict.http.Compressor;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.proto.TorchRecPredictProtos;
import com.aliyun.openservices.eas.predict.request.TorchRecRequest;
import com.aliyun.openservices.eas.predict.proto.TorchPredictProtos.ArrayProto;
import java.util.*;
public class TorchRecPredictTest {
public static PredictClient InitClient() {
return new PredictClient(new HttpConfig());
}
public static TorchRecRequest buildPredictRequest() {
TorchRecRequest TorchRecRequest = new TorchRecRequest();
TorchRecRequest.appendItemId("7033");
TorchRecRequest.addUserFeature("user_id", 33981,"int");
ArrayList<Double> list = new ArrayList<>();
list.add(0.24689289764507472);
list.add(0.005758482924454689);
list.add(0.6765301324940026);
list.add(0.18137273055602343);
TorchRecRequest.addUserFeature("raw_3", list,"List<double>");
Map<String,Integer> myMap =new LinkedHashMap<>();
myMap.put("866", 4143);
myMap.put("1627", 2451);
TorchRecRequest.addUserFeature("map_1", myMap,"map<string,int>");
ArrayList<ArrayList<Float>> list2 = new ArrayList<>();
ArrayList<Float> innerList1 = new ArrayList<>();
innerList1.add(1.1f);
innerList1.add(2.2f);
innerList1.add(3.3f);
list2.add(innerList1);
ArrayList<Float> innerList2 = new ArrayList<>();
innerList2.add(4.4f);
innerList2.add(5.5f);
list2.add(innerList2);
TorchRecRequest.addUserFeature("click", list2,"list<list<float>>");
TorchRecRequest.addContextFeature("id_2", list,"List<double>");
TorchRecRequest.addContextFeature("id_2", list,"List<double>");
System.out.println(TorchRecRequest.request);
return TorchRecRequest;
}
public static void main(String[] args) throws Exception{
PredictClient client = InitClient();
client.setToken("tokenGeneratedFromService");
client.setEndpoint("175805416243****.cn-beijing.pai-eas.aliyuncs.com");
client.setModelName("alirec_rank_with_fg");
client.setRequestTimeout(100000);
testInvoke(client);
testDebugLevel(client);
client.shutdown();
}
public static void testInvoke(PredictClient client) throws Exception {
long startTime = System.currentTimeMillis();
TorchRecPredictProtos.PBResponse response = client.predict(buildPredictRequest());
for (Map.Entry<String, ArrayProto> entry : response.getMapOutputsMap().entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
long endTime = System.currentTimeMillis();
System.out.println("Spend Time: " + (endTime - startTime) + "ms");
}
public static void testDebugLevel(PredictClient client) throws Exception {
long startTime = System.currentTimeMillis();
TorchRecRequest request = buildPredictRequest();
request.setDebugLevel(1);
TorchRecPredictProtos.PBResponse response = client.predict(request);
Map<String, String> genFeas = response.getGenerateFeaturesMap();
for(String itemId: genFeas.keySet()) {
System.out.println(itemId);
System.out.println(genFeas.get(itemId));
}
long endTime = System.currentTimeMillis();
System.out.println("Spend Time: " + (endTime - startTime) + "ms");
}
}
Les paramètres clés sont les suivants :
client.setToken("tokenGeneratedFromService"): Remplacez la valeur entre parenthèses par votre jeton de service. Par exemple :
MmFiMDdlO****wYjhhNjgwZmZjYjBjMTM1YjliZmNkODhjOGVi****.client.setEndpoint("175805416243.cn-beijing.pai-eas.aliyuncs.com"): Remplacez la valeur entre parenthèses par votre endpoint de service. Par exemple :
175805416243****.cn-beijing.pai-eas.aliyuncs.com.client.setModelName("alirec_rank_with_fg"): Remplacez la valeur entre parenthèses par le nom de votre service.
EAS Python SDK
Avant d'exécuter le code, installez ou mettez à jour la bibliothèque eas-prediction en exécutant la commande pip install -U eas-prediction --user. Pour plus de détails sur la configuration, consultez la rubrique Utilisation du SDK Python. Le code source est disponible à l'adresse https://github.com/pai-eas/eas-python-sdk/blob/master/eas_prediction/torchrec_request.py. Voici un exemple de code :
from eas_prediction import PredictClient
from eas_prediction.torchrec_request import TorchRecRequest
if __name__ == '__main__':
endpoint = 'http://localhost:6016'
client = PredictClient(endpoint, '<YOUR_SERVICE_NAME>')
client.set_token('<your_service_token>')
client.init()
torchrec_req = TorchRecRequest()
torchrec_req.add_user_fea('user_id', 'u001d', "STRING")
torchrec_req.add_user_fea('age', 12, "INT")
torchrec_req.add_user_fea('weight', 129.8, "FLOAT")
torchrec_req.add_item_id('item_0001')
torchrec_req.add_item_id('item_0002')
torchrec_req.add_item_id('item_0003')
torchrec_req.add_user_fea("raw_3", [0.24689289764507472, 0.005758482924454689, 0.6765301324940026, 0.18137273055602343], "list<double>")
torchrec_req.add_user_fea("raw_4", [0.9965264740966043, 0.659596586238391, 0.16396649403055896, 0.08364986620265635], "list<double>")
torchrec_req.add_user_fea("map_1", {"0":0.37845234405201145}, "map<int,float>")
torchrec_req.add_user_fea("map_2", {"866":4143,"1627":2451}, "map<int,int>")
torchrec_req.add_context_fea("id_2", [866], "list<int>" )
torchrec_req.add_context_fea("id_2", [7022,1], "list<int>" )
torchrec_req.add_context_fea("id_2", [7022,1], "list<int>" )
torchrec_req.add_user_fea("click", [[0.94433516,0.49145547], [0.94433516, 0.49145597]], "list<list<float>>")
res = client.predict(torchrec_req)
print(res)
Les configurations clés sont les suivantes :
endpoint: Définissez ce paramètre avec votre endpoint de service. Par exemple :
http://175805416243****.cn-beijing.pai-eas.aliyuncs.com/.<your_service_name>: Remplacez cet espace réservé par le nom de votre service.
<your_service_token>: Remplacez cet espace réservé par votre jeton de service. Par exemple :
MmFiMDdlO****wYjhhNjgwZmZjYjBjMTM1YjliZmNkODhjOGVi****.
Sans FG (fg_mode='bypass')
EAS Java SDK
Avant d'exécuter le code, configurez votre environnement Maven. Pour plus d'informations, consultez la rubrique Utiliser le SDK Java. Pour obtenir la dernière version du SDK, consultez le projet sur GitHub. L'exemple suivant montre comment envoyer une requête au service alirec_rank_no_fg :
package com.aliyun.openservices.eas.predict;
import java.util.List;
import java.util.Arrays;
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.request.TorchDataType;
import com.aliyun.openservices.eas.predict.request.TorchRequest;
import com.aliyun.openservices.eas.predict.response.TorchResponse;
public class Test_Torch {
public static PredictClient InitClient() {
return new PredictClient(new HttpConfig());
}
public static TorchRequest buildPredictRequest() {
TorchRequest request = new TorchRequest();
float[] content = new float[2304000];
for (int i = 0; i < content.length; i++) {
content[i] = (float) 0.0;
}
long[] content_i = new long[900];
for (int i = 0; i < content_i.length; i++) {
content_i[i] = 0;
}
long[] a = Arrays.copyOfRange(content_i, 0, 300);
float[] b = Arrays.copyOfRange(content, 0, 230400);
request.addFeed(0, TorchDataType.DT_INT64, new long[]{300,3}, content_i);
request.addFeed(1, TorchDataType.DT_FLOAT, new long[]{300,10,768}, content);
request.addFeed(2, TorchDataType.DT_FLOAT, new long[]{300,768}, b);
request.addFeed(3, TorchDataType.DT_INT64, new long[]{300}, a);
request.addFetch(0);
request.setDebugLevel(903);
return request;
}
public static void main(String[] args) throws Exception {
PredictClient client = InitClient();
client.setToken("tokenGeneratedFromService");
client.setEndpoint("175805416243****.cn-beijing.pai-eas.aliyuncs.com");
client.setModelName("alirec_rank_no_fg");
client.setIsCompressed(false);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
TorchResponse response = null;
try {
response = client.predict(buildPredictRequest());
List<Float> result = response.getFloatVals(0);
System.out.print("Predict Result: [");
for (int j = 0; j < result.size(); j++) {
System.out.print(result.get(j).floatValue());
if (j != result.size() - 1) {
System.out.print(", ");
}
}
System.out.print("]\n");
} catch (Exception e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("Spend Time: " + (endTime - startTime) + "ms");
client.shutdown();
}
}
Les paramètres clés sont les suivants :
client.setToken("tokenGeneratedFromService") : Remplacez la valeur fictive par votre jeton de service. Par exemple :
MmFiMDdlO****wYjhhNjgwZmZjYjBjMTM1YjliZmNkODhjOGVi****.client.setEndpoint("175805416243.cn-beijing.pai-eas.aliyuncs.com") : Remplacez la valeur fictive par votre endpoint de service. Par exemple :
175805416243****.cn-beijing.pai-eas.aliyuncs.com.client.setModelName("alirec_rank_no_fg") : Remplacez la valeur fictive par le nom de votre service.
EAS Python SDK
Avant d'exécuter le code, exécutez pip install -U eas-prediction --user pour installer ou mettre à jour la bibliothèque eas-prediction. Pour plus d'informations, consultez la rubrique Utiliser le SDK Python. L'exemple suivant montre comment envoyer une requête au service alirec_rank_no_fg :
from eas_prediction import PredictClient
from eas_prediction import TorchRequest
# snappy data
req = TorchRequest(False)
req.add_feed(0, [300, 3], TorchRequest.DT_INT64, [1] * 900)
req.add_feed(1, [300, 10, 768], TorchRequest.DT_FLOAT, [1.0] * 3 * 768000)
req.add_feed(2, [300, 768], TorchRequest.DT_FLOAT, [1.0] * 3 * 76800)
req.add_feed(3, [300], TorchRequest.DT_INT64, [1] * 300)
client = PredictClient('<your_endpoint>', '<your_service_name>')
client.set_token('<your_service_token>')
client.init()
resp = client.predict(req)
print(resp)
Les configurations clés sont les suivantes :
<your_endpoint> : Remplacez cet espace réservé par votre endpoint de service. Par exemple :
http://175805416243****.cn-beijing.pai-eas.aliyuncs.com/.<your_service_name> : Remplacez cet espace réservé par le nom de votre service.
<your_service_token> : Remplacez cet espace réservé par votre jeton de service. Par exemple :
MmFiMDdlO****wYjhhNjgwZmZjYjBjMTM1YjliZmNkODhjOGVi****.
Pour plus de détails sur les codes d'état du service, consultez la section Codes d'état du service. Pour construire une requête de service, reportez-vous également à la section Format de la requête.
Format de la requête
Pour appeler le service, vous pouvez générer le code de requête de prédiction à partir du fichier .proto. Vous pouvez également construire la requête vous-même en utilisant les définitions Protobuf suivantes :
pytorch_predict.proto: modèles Torch
syntax = "proto3";
package pytorch.eas;
option cc_enable_arenas = true;
option java_package = "com.aliyun.openservices.eas.predict.proto";
option java_outer_classname = "TorchPredictProtos";
enum ArrayDataType {
// Not a legal value for DataType. Used to indicate that a DataType field
// has not been set.
DT_INVALID = 0;
// Data types that all computation devices are expected to support.
DT_FLOAT = 1;
DT_DOUBLE = 2;
DT_INT32 = 3;
DT_UINT8 = 4;
DT_INT16 = 5;
DT_INT8 = 6;
DT_STRING = 7;
DT_COMPLEX64 = 8; // Single-precision complex
DT_INT64 = 9;
DT_BOOL = 10;
DT_QINT8 = 11; // Quantized int8
DT_QUINT8 = 12; // Quantized uint8
DT_QINT32 = 13; // Quantized int32
DT_BFLOAT16 = 14; // Float32 truncated to 16 bits. Only for cast ops.
DT_QINT16 = 15; // Quantized int16
DT_QUINT16 = 16; // Quantized uint16
DT_UINT16 = 17;
DT_COMPLEX128 = 18; // Double-precision complex
DT_HALF = 19;
DT_RESOURCE = 20;
DT_VARIANT = 21; // Arbitrary C++ data types
}
// Dimensions of an array.
message ArrayShape {
repeated int64 dim = 1 [packed = true];
}
// Represents an array.
message ArrayProto {
// Data type.
ArrayDataType dtype = 1;
// Array shape.
ArrayShape array_shape = 2;
// DT_FLOAT.
repeated float float_val = 3 [packed = true];
// DT_DOUBLE.
repeated double double_val = 4 [packed = true];
// DT_INT32, DT_INT16, DT_INT8, DT_UINT8.
repeated int32 int_val = 5 [packed = true];
// DT_STRING.
repeated bytes string_val = 6;
// DT_INT64.
repeated int64 int64_val = 7 [packed = true];
}
message PredictRequest {
// Input tensors.
repeated ArrayProto inputs = 1;
// Output filter.
repeated int32 output_filter = 2;
// Input tensors for the recommendation model.
map<string, ArrayProto> map_inputs = 3;
// Debug level for the recommendation model.
int32 debug_level = 100;
}
// Response for a successful PredictRequest.
message PredictResponse {
// Output tensors.
repeated ArrayProto outputs = 1;
// Output tensors from the recommendation model.
map<string, ArrayProto> map_outputs = 2;
}
torchrec_predict.proto: modèle Torch avec FG
syntax = "proto3";
option go_package = ".;torch_predict_protos";
option java_package = "com.aliyun.openservices.eas.predict.proto";
option java_outer_classname = "TorchRecPredictProtos";
package com.alibaba.pairec.processor;
import "pytorch_predict.proto";
// Mappings from int64.
message LongStringMap {
map<int64, string> map_field = 1;
}
message LongIntMap {
map<int64, int32> map_field = 1;
}
message LongLongMap {
map<int64, int64> map_field = 1;
}
message LongFloatMap {
map<int64, float> map_field = 1;
}
message LongDoubleMap {
map<int64, double> map_field = 1;
}
// Mappings from string.
message StringStringMap {
map<string, string> map_field = 1;
}
message StringIntMap {
map<string, int32> map_field = 1;
}
message StringLongMap {
map<string, int64> map_field = 1;
}
message StringFloatMap {
map<string, float> map_field = 1;
}
message StringDoubleMap {
map<string, double> map_field = 1;
}
// Mappings from int32.
message IntStringMap {
map<int32, string> map_field = 1;
}
message IntIntMap {
map<int32, int32> map_field = 1;
}
message IntLongMap {
map<int32, int64> map_field = 1;
}
message IntFloatMap {
map<int32, float> map_field = 1;
}
message IntDoubleMap {
map<int32, double> map_field = 1;
}
// Single-level lists.
message IntList {
repeated int32 features = 1;
}
message LongList {
repeated int64 features = 1;
}
message FloatList {
repeated float features = 1;
}
message DoubleList {
repeated double features = 1;
}
message StringList {
repeated string features = 1;
}
// Nested lists.
message IntLists {
repeated IntList lists = 1;
}
message LongLists {
repeated LongList lists = 1;
}
message FloatLists {
repeated FloatList lists = 1;
}
message DoubleLists {
repeated DoubleList lists = 1;
}
message StringLists {
repeated StringList lists = 1;
}
message PBFeature {
oneof value {
int32 int_feature = 1;
int64 long_feature = 2;
string string_feature = 3;
float float_feature = 4;
double double_feature=5;
LongStringMap long_string_map = 6;
LongIntMap long_int_map = 7;
LongLongMap long_long_map = 8;
LongFloatMap long_float_map = 9;
LongDoubleMap long_double_map = 10;
StringStringMap string_string_map = 11;
StringIntMap string_int_map = 12;
StringLongMap string_long_map = 13;
StringFloatMap string_float_map = 14;
StringDoubleMap string_double_map = 15;
IntStringMap int_string_map = 16;
IntIntMap int_int_map = 17;
IntLongMap int_long_map = 18;
IntFloatMap int_float_map = 19;
IntDoubleMap int_double_map = 20;
IntList int_list = 21;
LongList long_list =22;
StringList string_list = 23;
FloatList float_list = 24;
DoubleList double_list = 25;
IntLists int_lists = 26;
LongLists long_lists =27;
StringLists string_lists = 28;
FloatLists float_lists = 29;
DoubleLists double_lists = 30;
}
}
// Context features.
message ContextFeatures {
repeated PBFeature features = 1;
}
// Defines the request sent to the aggregator.
message PBRequest {
// Debug level.
int32 debug_level = 1;
// User features, keyed by the input name.
map<string, PBFeature> user_features = 2;
// Item IDs.
repeated string item_ids = 3;
// Context features for each item, keyed by the input name.
map<string, ContextFeatures> context_features = 4;
// The number of nearest neighbors to retrieve from Faiss.
int32 faiss_neigh_num = 5;
// Item features for each item, keyed by the input name.
map<string, ContextFeatures> item_features = 6;
// Optional metadata.
map<string, string> meta_data = 7;
}
// Defines the response from the aggregator.
message PBResponse {
// Torch output tensors.
map<string, pytorch.eas.ArrayProto> map_outputs = 1;
// Output features from the feature generator (FG).
map<string, string> generate_features = 2;
// All input features for the feature generator (FG).
map<string, string> raw_features = 3;
// Item IDs.
repeated string item_ids = 4;
// Pass-through data configured in the model.
map<string, string> pass_through_data = 5;
}
Le paramètre debug_level est défini comme suit :
La configuration n'est requise qu'à des fins de débogage.
**Valeur**
|
**Description**
| | --- | --- | |
0
|
Effectue une prédiction standard.
| |
1
|
Valide la `request key`, effectue une `shape validation` sur les entrées et sorties `FG`, et renvoie les `input features` et `output features` sans effectuer de prédiction.
| |
2
|
Valide la `request key`, effectue une `shape validation` sur les entrées et sorties `FG`, renvoie les `input features`, les `output features` et le `tensor` d'entrée du modèle, puis effectue une prédiction.
| |
3
|
Valide la `request key`, effectue une `shape validation` sur les entrées et sorties `FG`, et renvoie les `output features` sans effectuer de prédiction.
| |
100
|
Enregistre la requête de prédiction, y compris la requête d'origine, les `input features`, les `output features` et le `tensor` envoyé au `model`, dans un `Protobuf file` situé dans le chemin spécifié par le paramètre `request_log_path`.
| |
102
|
Effectue un `vector recall`, valide la `request key`, effectue une `shape validation` sur les entrées et sorties `FG`, et enregistre les `input features`, les `output features`, le `tensor` d'entrée du modèle et le résultat `user embedding`.
| |
903
|
Enregistre le `prediction time` pour chaque étape.
| |
904
|
Vérifie l'absence de `feature fields` dans la requête et les enregistre dans le `log`.
|
Codes d'état du service
Cette section décrit les principaux codes d'état du service TorchEasyRec. Pour les codes d'état du service EAS, consultez l'Annexe : Codes d'état du service et erreurs courantes.
|**Code d'état**
|
**Description**
| | --- | --- | |
200
|
La requête a abouti.
| |
400
|
Requête invalide.
| |
500
|
Échec de la prédiction. Consultez le journal du service pour plus d'informations.
|
Enregistrer et analyser une requête Protobuf
Dans la version 1.12 ou ultérieure du processeur, vous pouvez activer le mode débogage en définissant debug=True dans le corps de la requête du moteur PAI-REC. Cela permet d'enregistrer la requête d'origine ainsi que les fonctionnalités d'entrée et de sortie côté élément dans un fichier protobuf à des fins d'analyse et de validation. Pour utiliser cette fonctionnalité, définissez le paramètre request_log_path sur le chemin de destination et montez OSS sur ce chemin. Par exemple :
"model_config": {
"fg_mode": "normal",
"fg_threads": 8,
"request_log_path": "/request_log",
"background_feature_thread_num": 8
},
"storage": [
{
"mount_path": "/request_log",
"oss": {
"path": "oss://my-bucket/my-model/myrequests/",
"readOnly": false
}
},
{
"mount_path": "/home/admin/docker_ml/workspace/model/",
"oss": {
"path": "oss://my-bucket/my-model/20260316",
"readOnly": false
}
}
]
Le processeur crée un sous-répertoire date_hour dans le chemin spécifié par request_log_path pour enregistrer les données de requête. Des threads d'arrière-plan écrivent ces données sur le disque de manière asynchrone. Utilisez le paramètre model_config.background_feature_thread_num pour configurer le nombre de threads d'arrière-plan. La valeur par défaut est 4 ; l'augmenter peut améliorer le débit d'écriture. Les fichiers Protobuf écrits sur le disque utilisent le format <request_id>_<random_str>.pb. En raison de la bande passante d'écriture limitée d'OSS, n'activez pas le mode débogage pour les volumes de requêtes élevés dans le moteur PAI-REC. Si les écritures sur disque prennent du retard, la file d'attente interne du service de modèle rejette les nouvelles requêtes.
Pour analyser le fichier protobuf, vous devez utiliser EAS-Python-SDK 0.35 ou une version ultérieure, ou EAS-Java-SDK 2.0.29 ou une version ultérieure. L'exemple suivant montre comment procéder en Python :
from eas_prediction.torchrec_predict_pb2 import PBLogData
with open('xxxx.pb', 'rb') as f:
pb_data = f.read()
pb_log = PBLogData()
pb_log.ParseFromString(pb_data)
print(pb_log) # Print the entire log
print(pb_log.request) # Print the request
print(pb_log.raw_features) # Print the raw item-side features
print(pb_log.generate_features) # Print the item-side generated features
Préchauffage du service de modèle
Lorsqu'un service de modèle démarre ou est mis à jour, il peut connaître des pics de temps de réponse. Pour atténuer ces pics, configurez la fonctionnalité de préchauffage pour le processeur. Par exemple, dans easyrec-torch-1.5 et les versions ultérieures, vous pouvez activer cette fonctionnalité en ajoutant trois paramètres à model_config.
"warmup_data_path": "/warmup", # Enables warmup and sets the path for the warmup files.
"warmup_cnt_per_file": 20, # Number of warmup iterations per file. A higher value results in a more thorough warmup.
"warmup_pb_files_count": 64 # Number of online requests to save as protobuf files for warmup. A higher value helps cover more data patterns.
Pour persister les fichiers protobuf, configurez un montage OSS dans la section storage au niveau du warmup_data_path. Par exemple :
"storage": [
...,
{
"mount_path": "/warmup",
"oss": {
"path": "oss://<warmup Protobuf file path>",
"readOnly": false
}
}
]
Lors de son premier démarrage après configuration, le processeur capture et enregistre le nombre de requêtes en ligne spécifié par warmup_pb_files_count. Lors des redémarrages suivants, il utilise ces fichiers protobuf enregistrés pour le préchauffage.