华为云用户手册

  • 模型包规范 模型包必须存储在OBS中,且必须以“model”命名。“model”文件夹下面放置模型文件、模型推理代码。 模型推理代码文件必选,其文件名必须为“customize_service.py”,“model”文件夹下有且只能有1个推理代码文件,模型推理代码编写请参见模型推理代码编写说明。 使用模板导入的模型包结构如下所示: model/ │ ├── 模型文件 //必选,不同的框架,其模型文件格式不同,详细可参考模型包示例。 ├── 自定义Python包 //可选,用户自有的Python包,在模型推理代码中可以直接引用。 ├── customize_service.py //必选,模型推理代码,文件名称必须为“customize_service.py”,否则不视为推理代码。
  • 模型包规范 模型包必须存储在OBS中,且必须以“model”命名。“model”文件夹下面放置模型文件、模型推理代码。 模型推理代码文件必选,其文件名必须为“customize_service.py”,“model”文件夹下有且只能有1个推理代码文件,模型推理代码编写请参见模型推理代码编写说明。 使用模板导入的模型包结构如下所示: model/ │ ├── 模型文件 //必选,不同的框架,其模型文件格式不同,详细可参考模型包示例。 ├── 自定义Python包 //可选,用户自有的Python包,在模型推理代码中可以直接引用。 ├── customize_service.py //必选,模型推理代码,文件名称必须为“customize_service.py”,否则不视为推理代码。
  • 模型包规范 模型包必须存储在OBS中,且必须以“model”命名。“model”文件夹下面放置模型文件、模型推理代码。 模型推理代码文件必选,其文件名必须为“customize_service.py”,“model”文件夹下有且只能有1个推理代码文件,模型推理代码编写请参见模型推理代码编写说明。 使用模板导入的模型包结构如下所示: model/ │ ├── 模型文件 //必选,不同的框架,其模型文件格式不同,详细可参考模型包示例。 ├── 自定义Python包 //可选,用户自有的Python包,在模型推理代码中可以直接引用。 ├── customize_service.py //必选,模型推理代码,文件名称必须为“customize_service.py”,否则不视为推理代码。
  • 模型包规范 模型包必须存储在OBS中,且必须以“model”命名。“model”文件夹下面放置模型文件、模型推理代码。 模型推理代码文件必选,其文件名必须为“customize_service.py”,“model”文件夹下有且只能有1个推理代码文件,模型推理代码编写请参见模型推理代码编写说明。 使用模板导入的模型包结构如下所示: model/ │ ├── 模型文件 //必选,不同的框架,其模型文件格式不同,详细可参考模型包示例。 ├── 自定义Python包 //可选,用户自有的Python包,在模型推理代码中可以直接引用。 ├── customize_service.py //必选,模型推理代码,文件名称必须为“customize_service.py”,否则不视为推理代码。
  • 模型包规范 模型包必须存储在OBS中,且必须以“model”命名。“model”文件夹下面放置模型文件、模型推理代码。 模型推理代码文件必选,其文件名必须为“customize_service.py”,“model”文件夹下有且只能有1个推理代码文件,模型推理代码编写请参见模型推理代码编写说明。 使用模板导入的模型包结构如下所示: model/ │ ├── 模型文件 //必选,不同的框架,其模型文件格式不同,详细可参考模型包示例。 ├── 自定义Python包 //可选,用户自有的Python包,在模型推理代码中可以直接引用。 ├── customize_service.py //必选,模型推理代码,文件名称必须为“customize_service.py”,否则不视为推理代码。
  • 简介 搭载TensorFlow1.8引擎,运行环境为“python2.7”,适合导入以“SavedModel”格式保存的TensorFlow图像分类模型。该模板使用平台预置的图像处理模式,模式详情参见预置图像处理模式,推理时向模型输入一张“key”为“images”的待处理图片,所以需确保您的模型能处理“key”为“images”的输入。使用该模板导入模型时请选择到包含模型文件的“model”目录。
  • 模型包规范 模型包必须存储在OBS中,且必须以“model”命名。“model”文件夹下面放置模型文件、模型推理代码。 模型推理代码文件必选,其文件名必须为“customize_service.py”,“model”文件夹下有且只能有1个推理代码文件,模型推理代码编写请参见模型推理代码编写说明。 使用模板导入的模型包结构如下所示: model/ │ ├── 模型文件 //必选,不同的框架,其模型文件格式不同,详细可参考模型包示例。 ├── 自定义Python包 //可选,用户自有的Python包,在模型推理代码中可以直接引用。 ├── customize_service.py //必选,模型推理代码,文件名称必须为“customize_service.py”,否则不视为推理代码。
  • 支持的模板 TensorFlow图像分类模板 TensorFlow-py27通用模板 TensorFlow-py36通用模板 MXNet-py27通用模板 MXNet-py36通用模板 PyTorch-py27通用模板 PyTorch-py36通用模板 Caffe-CPU-py27通用模板 Caffe-GPU-py27通用模板 Caffe-CPU-py36通用模板 Caffe-GPU-py36通用模板 ARM-Ascend模板
  • 背景信息 模板分两大类型:通用类型,非通用类型。 非通用类型模板,针对特定的场景所定制的,固定输入输出模式,不可覆盖,如“TensorFlow图像分类模板”,固定使用预置图像处理模式。 通用模板,搭载特定的AI引擎以及运行环境,内置的输入输出模式为未定义模式,即不定义具体的输入输出格式,用户需根据模型功能或业务场景重新选择新的输入输出模式来覆盖内置的未定义模式,如图像分类模型应选择预置图像处理模式,而目标检测模型则应选择预置物体检测模式。 使用未定义模式的模型将无法部署批量服务。
  • XGBoost的推理脚本示例 更多机器学习引擎的推理代码请参考Pyspark、Scikit Learn。 # coding:utf-8 import collections import json import xgboost as xgb from model_service.python_model_service import XgSklServingBaseService class UserService(XgSklServingBaseService): # request data preprocess def _preprocess(self, data): list_data = [] json_data = json.loads(data, object_pairs_hook=collections.OrderedDict) for element in json_data["data"]["req_data"]: array = [] for each in element: array.append(element[each]) list_data.append(array) return list_data # predict def _inference(self, data): xg_model = xgb.Booster(model_file=self.model_path) pre_data = xgb.DMatrix(data) pre_result = xg_model.predict(pre_data) pre_result = pre_result.tolist() return pre_result # predict result process def _postprocess(self, data): resp_data = [] for element in data: resp_data.append({"predict_result": element}) return resp_data
  • 自定义推理逻辑的推理脚本示例 首先,需要在配置文件中,定义自己的依赖包,详细示例请参见使用自定义依赖包的模型配置文件示例。然后通过如下示例代码,实现了“saved_model”格式模型的加载推理。 当前推理基础镜像使用的python的logging模块,采用的是默认的日志级别Warnning,即当前只有warning级别的日志可以默认查询出来。如果想要指定INFO等级的日志能够查询出来,需要在代码中指定logging的输出日志等级为INFO级别。
  • MindSpore的推理脚本示例 snt3芯片目前只有北京四提工单申请权限后才可以使用,支持模型格式为.om,推理脚本如下: from __future__ import absolute_import from __future__ import division from __future__ import print_function import json import os import numpy as np from PIL import Image from hiai.nn_tensor_lib import NNTensor from hiai.nntensor_list import NNTensorList from model_service.hiai_model_service import HiaiBaseService class DemoService(HiaiBaseService): def __init__(self, *args, **kwargs): # 默认加载模型包目录下的om文件 super(DemoService, self).__init__(*args, **kwargs) self.labels_list = None self.is_multilabel = False def _preprocess(self, data): preprocessed_data = {} images = [] for k, v in data.items(): for file_name, file_content in v.items(): image = Image.open(file_content) image = np.array(image) # NHWC # AIPP should use RGB format. # mean reg is applied in AIPP. # Transpose is applied in AIPP tensor = NNTensor(image) images.append(tensor) tensor_list = NNTensorList(images) preprocessed_data['images'] = tensor_list return preprocessed_data def _inference(self, data, image_info=None): result = {} for k, v in data.items(): result[k] = self.model.proc(v) return result def _postprocess(self, data): # 这里增加自己的后处理 return str(data)
  • TensorFlow的推理脚本示例 TensorFlow MnistService示例如下。更多TensorFlow推理代码示例请参考TensorFlow、TensorFlow 2.1。其他引擎推理代码请参考PyTorch、Caffe。 推理代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from PIL import Image import numpy as np from model_service.tfserving_model_service import TfServingBaseService class MnistService(TfServingBaseService): def _preprocess(self, data): preprocessed_data = {} for k, v in data.items(): for file_name, file_content in v.items(): image1 = Image.open(file_content) image1 = np.array(image1, dtype=np.float32) image1.resize((1, 784)) preprocessed_data[k] = image1 return preprocessed_data def _postprocess(self, data): infer_output = {} for output_name, result in data.items(): infer_output["mnist_result"] = result[0].index(max(result[0])) return infer_output 请求 curl -X POST \ 在线服务地址 \ -F images=@test.jpg 返回 {"mnist_result": 7} 在上面的代码示例中,完成了将用户表单输入的图片的大小调整,转换为可以适配模型输入的shape。首先通过Pillow库读取“32×32”的图片,调整图片大小为“1×784”以匹配模型输入。在后续处理中,转换模型输出为列表,用于Restful接口输出展示。
  • 使用自定义依赖包的模型配置文件示例 如下示例中,定义了1.16.4版本的numpy的依赖环境。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 { "model_algorithm": "image_classification", "model_type": "TensorFlow", "runtime": "python3.6", "apis": [ { "url": "/", "method": "post", "request": { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "images": { "type": "file" } } } }, "response": { "Content-type": "applicaton/json", "data": { "type": "object", "properties": { "mnist_result": { "type": "array", "item": [ { "type": "string" } ] } } } } } ], "metrics": { "f1": 0.124555, "recall": 0.171875, "precision": 0.00234938928519385, "accuracy": 0.00746268656716417 }, "dependencies": [ { "installer": "pip", "packages": [ { "restraint": "EXACT", "package_version": "1.16.4", "package_name": "numpy" } ] } ] }
  • 机器学习类型的模型配置文件示例 以下代码以XGBoost为例。 模型输入: { "req_data": [ { "sepal_length": 5, "sepal_width": 3.3, "petal_length": 1.4, "petal_width": 0.2 }, { "sepal_length": 5, "sepal_width": 2, "petal_length": 3.5, "petal_width": 1 }, { "sepal_length": 6, "sepal_width": 2.2, "petal_length": 5, "petal_width": 1.5 } ] } 模型输出: { "resp_data": [ { "predict_result": "Iris-setosa" }, { "predict_result": "Iris-versicolor" } ] } 配置文件: { "model_type": "XGBoost", "model_algorithm": "xgboost_iris_test", "runtime": "python2.7", "metrics": { "f1": 0.345294, "accuracy": 0.462963, "precision": 0.338977, "recall": 0.351852 }, "apis": [ { "url": "/", "method": "post", "request": { "Content-type": "application/json", "data": { "type": "object", "properties": { "req_data": { "items": [ { "type": "object", "properties": {} } ], "type": "array" } } } }, "response": { "Content-type": "applicaton/json", "data": { "type": "object", "properties": { "resp_data": { "type": "array", "items": [ { "type": "object", "properties": { "predict_result": {} } } ] } } } } } ] }
  • 自定义镜像 类型的模型配置文件示例 模型输入和输出与目标检测模型配置文件示例类似。 模型预测输入为图片类型时,request请求示例如下: 该实例表示模型预测接收一个参数名为images、参数类型为file的预测请求,在推理界面会显示文件上传按钮,以文件形式进行预测。 1 2 3 4 5 6 7 8 9 10 11 { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "images": { "type": "file" } } } } 模型预测输入为json数据类型时,request请求示例如下: 该实例表示模型预测接收json请求体,只有一个参数名为input、参数类型为string的预测请求,在推理界面会显示文本输入框,用于填写预测请求。 1 2 3 4 5 6 7 8 9 10 11 { "Content-type": "application/json", "data": { "type": "object", "properties": { "input": { "type": "string" } } } } 完整请求示例如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 { "model_algorithm": "image_classification", "model_type": "Image", "metrics": { "f1": 0.345294, "accuracy": 0.462963, "precision": 0.338977, "recall": 0.351852 }, "apis": [{ "url": "/", "method": "post", "request": { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "images": { "type": "file" } } } }, "response": { "Content-type": "application/json", "data": { "type": "object", "required": [ "predicted_label", "scores" ], "properties": { "predicted_label": { "type": "string" }, "scores": { "type": "array", "items": [{ "type": "array", "minItems": 2, "maxItems": 2, "items": [{ "type": "string" }, { "type": "number" } ] }] } } } } }] }
  • 预测分析模型配置文件示例 如下代码以TensorFlow引擎为例,您可以根据实际使用的引擎类型修改model_type参数后使用。 模型输入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 { "data": { "req_data": [ { "buying_price": "high", "maint_price": "high", "doors": "2", "persons": "2", "lug_boot": "small", "safety": "low", "acceptability": "acc" }, { "buying_price": "high", "maint_price": "high", "doors": "2", "persons": "2", "lug_boot": "small", "safety": "low", "acceptability": "acc" } ] } } 模型输出 1 2 3 4 5 6 7 8 9 10 11 12 { "data": { "resp_data": [ { "predict_result": "unacc" }, { "predict_result": "unacc" } ] } } 配置文件 代码中request结构和response结构中的data参数是json schema数据结构。data/properties里面的内容对应“模型输入”和“模型输出”。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 { "model_type": "TensorFlow", "model_algorithm": "predict_analysis", "runtime": "tensorflow_2.1.0-cuda_10.1-py_3.7-ubuntu_18.04-x86_64", "metrics": { "f1": 0.345294, "accuracy": 0.462963, "precision": 0.338977, "recall": 0.351852 }, "apis": [ { "url": "/", "method": "post", "request": { "Content-type": "application/json", "data": { "type": "object", "properties": { "data": { "type": "object", "properties": { "req_data": { "items": [ { "type": "object", "properties": {} } ], "type": "array" } } } } } }, "response": { "Content-type": "application/json", "data": { "type": "object", "properties": { "data": { "type": "object", "properties": { "resp_data": { "type": "array", "items": [ { "type": "object", "properties": {} } ] } } } } } } } ], "dependencies": [ { "installer": "pip", "packages": [ { "restraint": "EXACT", "package_version": "1.15.0", "package_name": "numpy" }, { "restraint": "EXACT", "package_version": "5.2.0", "package_name": "Pillow" } ] } ] }
  • 图像分类模型配置文件示例 如下代码以TensorFlow引擎为例,您可以根据实际使用的引擎类型修改model_type参数后使用。 模型输入 key:images value:图片文件 模型输出 1 2 3 4 5 6 7 { "predicted_label": "flower", "scores": [ ["rose", 0.99], ["begonia", 0.01] ] } 配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 { "model_type": "TensorFlow", "model_algorithm": "image_classification", "runtime": "tensorflow_2.1.0-cuda_10.1-py_3.7-ubuntu_18.04-x86_64", "metrics": { "f1": 0.345294, "accuracy": 0.462963, "precision": 0.338977, "recall": 0.351852 }, "apis": [{ "url": "/", "method": "post", "request": { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "images": { "type": "file" } } } }, "response": { "Content-type": "application/json", "data": { "type": "object", "properties": { "predicted_label": { "type": "string" }, "scores": { "type": "array", "items": [{ "type": "array", "minItems": 2, "maxItems": 2, "items": [ { "type": "string" }, { "type": "number" } ] }] } } } } }], "dependencies": [{ "installer": "pip", "packages": [{ "restraint": "ATLEAST", "package_version": "1.15.0", "package_name": "numpy" }, { "restraint": "", "package_version": "", "package_name": "Pillow" } ] }] } 如下代码以MindSpore引擎为例,您可以根据实际使用的引擎类型修改model_type参数后使用。 模型输入 key:images value:图片文件 模型输出 1 "[[-2.404526 -3.0476532 -1.9888215 0.45013925 -1.7018927 0.40332815\n -7.1861157 11.290332 -1.5861531 5.7887416 ]]" 配置文件 { "model_algorithm": "image_classification", "model_type": "MindSpore", "runtime": "mindspore_2.1.0-cann_6.3.2-py_3.7-euler_2.10.7-aarch64-snt9b", "metrics": { "f1": 0.124555, "recall": 0.171875, "precision": 0.0023493892851938493, "accuracy": 0.00746268656716417 }, "apis": [{ "url": "/", "method": "post", "request": { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "images": { "type": "file" } } } }, "response": { "Content-type": "applicaton/json", "data": { "type": "object", "properties": { "mnist_result": { "type": "array", "item": [{ "type": "string" }] } } } } } ], "dependencies": [] }
  • 目标检测模型配置文件示例 如下代码以TensorFlow引擎为例,您可以根据实际使用的引擎类型修改model_type参数后使用。 模型输入 key:images value:图片文件 模型输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 { "detection_classes": [ "face", "arm" ], "detection_boxes": [ [ 33.6, 42.6, 104.5, 203.4 ], [ 103.1, 92.8, 765.6, 945.7 ] ], "detection_scores": [0.99, 0.73] } 配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 { "model_type": "TensorFlow", "model_algorithm": "object_detection", "runtime": "tensorflow_2.1.0-cuda_10.1-py_3.7-ubuntu_18.04-x86_64", "metrics": { "f1": 0.345294, "accuracy": 0.462963, "precision": 0.338977, "recall": 0.351852 }, "apis": [{ "url": "/", "method": "post", "request": { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "images": { "type": "file" } } } }, "response": { "Content-type": "application/json", "data": { "type": "object", "properties": { "detection_classes": { "type": "array", "items": [{ "type": "string" }] }, "detection_boxes": { "type": "array", "items": [{ "type": "array", "minItems": 4, "maxItems": 4, "items": [{ "type": "number" }] }] }, "detection_scores": { "type": "array", "items": [{ "type": "number" }] } } } } }], "dependencies": [{ "installer": "pip", "packages": [{ "restraint": "EXACT", "package_version": "1.15.0", "package_name": "numpy" }, { "restraint": "EXACT", "package_version": "5.2.0", "package_name": "Pillow" } ] }] }
  • apis参数代码示例 [{ "url": "/", "method": "post", "request": { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "images": { "type": "file" } } } }, "response": { "Content-type": "applicaton/json", "data": { "type": "object", "properties": { "mnist_result": { "type": "array", "item": [ { "type": "string" } ] } } } } }]
  • 访问边缘服务 当边缘服务和边缘节点的状态都处于“运行中”状态,表示边缘服务已在边缘节点成功部署。 您可以通过以下两种方式,在能够访问到边缘节点的网络环境中,对部署在边缘节点上的边缘服务发起预测请求。 方式一:使用图形界面的软件进行预测(以Postman为例) 方式二:使用curl命令发送预测请求 通过方式一和方式二,边缘服务无需安全认证即可访问。如果用户需要设置安全认证,请选择使用自定义镜像创建的AI应用,具体操作请参考官方指导。在制作自定义镜像时,可参考Flask文档使用Flask设计RESTful的认证。
  • 方式一:使用图形界面的软件进行预测(以Postman为例) 下载Postman软件并安装,您可以直接在Chrome浏览器添加Postman扩展程序(也可使用其它支持发送post请求的软件)。 打开Postman,如图1所示。 图1 Postman软件界面 在Postman界面填写参数,以图像分类举例说明。 选择POST任务,将某个边缘节点的调用地址(通过边缘服务详情界面-节点信息页签查看)复制到POST后面的方框。 图2 POST参数填写 在Body页签,根据AI应用的输入参数不同,可分为“文件输入”或“文本输入”。 文件输入 选择“form-data”。在“KEY”值填写AI应用的入参,比如本例中预测图片的参数为“images”。然后在“VALUE”值,选择文件,上传一张待预测图片(当前仅支持单张图片预测)。 图3 填写Body配置 文本输入 选择“raw”,选择JSON(application/json)类型,在下方文本框中填写请求体,请求体样例如下。 { "meta": { "uuid": "10eb0091-887f-4839-9929-cbc884f1e20e" }, "data": { "req_data": [ { "sepal_length": 3, "sepal_width": 1, "petal_length": 2.2, "petal_width": 4 } ] } } 其中,“meta”中可携带“uuid”,返回预测结果时回传此“uuid”用于跟踪请求,如无此需要可不填写meta。“data”包含了一个“req_data”的数组,可传入单条或多条请求数据,其中每个数据的参数由AI应用决定,比如本例中的“sepal_length”、“sepal_width”等。 参数填写完成,单击“Send”发送请求,结果会在Response下的对话框里显示。 文件输入形式的预测结果样例如图4所示,返回结果的字段值根据不同AI应用可能有所不同。 图4 边缘服务文件输入预测结果 文本输入形式的预测结果样例如图5所示,请求体包含“meta”及“data”。如输入请求中包含“uuid”,则输出结果中回传此“uuid”。如未输入,则为空。“data”包含了一个“req_data”的数组,可传入单条或多条请求数据,其中每个数据的参数由AI应用决定,比如本例中的“sepal_length”、“sepal_width”等。 图5 边缘服务文本输入预测结果
  • 映射关系示例 如下示例展示了配置文件、映射规则、csv数据以及最终推理请求的关系。 假设,您的模型所用配置文件,其apis参数如下所示: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 [ { "method": "post", "url": "/", "request": { "Content-type": "multipart/form-data", "data": { "type": "object", "properties": { "data": { "type": "object", "properties": { "req_data": { "type": "array", "items": [ { "type": "object", "properties": { "input_1": { "type": "number" }, "input_2": { "type": "number" }, "input_3": { "type": "number" }, "input_4": { "type": "number" } } } ] } } } } } } } ] 此时,其对应的映射关系如下所示。ModelArts管理控制台将从配置文件中自动解析映射关系,如果您调用ModelArts API时,需要自行根据规则编写映射关系。 { "type": "object", "properties": { "data": { "type": "object", "properties": { "req_data": { "type": "array", "items": [ { "type": "object", "properties": { "input_1": { "type": "number", "index": 0 }, "input_2": { "type": "number", "index": 1 }, "input_3": { "type": "number", "index": 2 }, "input_4": { "type": "number", "index": 3 } } } ] } } } } } 用户需要进行推理的数据,即 CS V数据,格式如下所示。数据必须以英文逗号隔开。 5.1,3.5,1.4,0.2 4.9,3.0,1.4,0.2 4.7,3.2,1.3,0.2 根据定义好的映射关系,最终推理请求样例如下所示,与在线服务使用的格式类似: { "data": { "req_data": [{ "input_1": 5.1, "input_2": 3.5, "input_3": 1.4, "input_4": 0.2 }] } }
  • 方式三:使用Python语言通过AppCode认证鉴权方式发送预测请求 下载Python SDK并在开发工具中完成SDK配置。具体操作请参见在Python环境中集成API请求签名的SDK。 创建请求体,进行预测请求。 输入为文件格式 # coding=utf-8 import requests import os if __name__ == '__main__': # Config url, app code and file path. url = "在线服务的调用地址" # 认证用的app_code硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以app_code保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_APP_CODE。 app_code = os.environ["HUAWEICLOUD_APP_CODE"] file_path = "预测文件的本地路径" # Send request. headers = { 'X-Apig-AppCode': app_code } files = { 'images': open(file_path, 'rb') } resp = requests.post(url, headers=headers, files=files) # Print result print(resp.status_code) print(resp.text) “files”中的参数名由在线服务的输入参数决定,需要和“类型”为“file”的输入参数“名称”保持一致。此处以“images”为例。 输入为文本格式(json类型) 读取本地预测文件并进行base64编码的请求体示例如下: # coding=utf-8 import base64 import requests import os if __name__ == '__main__': # Config url, app code and request body. url = "在线服务的调用地址" # 认证用的app_code硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以app_code保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_APP_CODE。 app_code = os.environ["HUAWEICLOUD_APP_CODE"] file_path = "预测文件的本地路径" with open(file_path, "rb") as file: base64_data = base64.b64encode(file.read()).decode("utf-8") # Send request headers = { 'Content-Type': 'application/json', 'X-Apig-AppCode': app_code } body = { 'image': base64_data } resp = requests.post(url, headers=headers, json=body) # Print result print(resp.status_code) print(resp.text) “body”中的参数名由在线服务的输入参数决定,需要和“类型”为“string”的输入参数“名称”保持一致。此处以“image”为例。“body”中的base64_data值为string类型。
  • 方式二:使用Java语言通过AppKey+AppSecret认证鉴权方式发送预测请求 下载Java SDK并在开发工具中完成SDK配置。具体操作请参见在Java环境中集成API请求签名的SDK。 创建Java类,进行预测请求。 由于在APIG的Java SDK中,“request.setBody()”只支持String类型,所以只支持输入为文本格式的预测请求。 此处以json格式为例介绍读取本地预测文件并进行base64编码的请求体: // Package name of the demo. package com.apig.sdk.demo; import com.cloud.apigateway.sdk.utils.Client; import com.cloud.apigateway.sdk.utils.Request; import org.apache.http.HttpHeaders; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class MyAkSkTest { public static void main(String[] args) { String url = "在线服务的调用地址"; // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以appKey和appSecret保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_APP_KEY和HUAWEICLOUD_APP_SECRET。 String appKey = System.getenv("HUAWEICLOUD_APP_KEY"); String appSecret = System.getenv("HUAWEICLOUD_APP_SECRET"); String body = "{}"; try { // Create request Request request = new Request(); // Set the AK/AppSecret to sign and authenticate the request. request.setKey(appKey); request.setSecret(appSecret); // Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH. request.setMethod(HttpPost.METHOD_NAME); // Add header parameters request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); // Set a request URL in the format of https://{Endpoint}/{URI}. request.setUrl(url); // Special characters, such as the double quotation mark ("), contained in the body must be escaped. request.setBody(body); // Sign the request. HttpRequestBase signedRequest = Client.sign(request); // Send request. CloseableHttpResponse response = HttpClients.createDefault().execute(signedRequest); // Print result System.out.println(response.getStatusLine().getStatusCode()); System.out.println(EntityUtils.toString(response.getEntity())); } catch (Exception e) { e.printStackTrace(); } } } “body”由具体文本格式决定,此处以json为例。
  • APP认证鉴权 当支持APP认证功能的在线服务运行成功处于“运行中”状态,就可以对服务进行调用 。在调用之前您需要进行APP认证鉴权。 当使用APP认证,且开启了简易认证模式,API请求既可以选择使用Appkey和AppSecret做签名和校验,也可以选择使用AppCode进行简易认证(ModelArts默认启用简易认证)。推荐使用AppKey/AppSecret认证,其安全性比AppCode认证要高。 AppKey/AppSecret认证:通过AppKey与AppSecret对请求进行加密签名,可标识发送方并防止请求被修改。使用AppKey/AppSecret认证时,您需要使用专门的签名SDK对请求进行签名。 AppKey:APP访问密钥ID。与私有访问密钥关联的唯一标识符;访问密钥ID和私有访问密钥一起使用,对请求进行加密签名。 AppSecret:APP私有访问密钥,即与访问密钥ID结合使用的密钥,对请求进行加密签名,可标识发送方,并防止请求被修改。 AppKey进行简易认证时,即在调用API的时候,在HTTP请求头部消息增加一个参数“apikey”(参数值为“AppKey”),实现快速认证。 AppCode认证:通过AppCode认证通用请求。 AppCode认证就是在调用API的时候,在HTTP请求头部消息增加一个参数“X-Apig-AppCode”(参数值为“AppCode”),而不需要对请求内容签名,API网关也仅校验AppCode,不校验请求签名,从而实现快速响应。 您可以在服务详情页的“调用指南”页签(如图5)或者在线服务授权管理页面(如图2)获取API接口和AppKey/AppSecret和AppCode。请注意使用图中红框所示的API接口公网地址。当模型配置文件中apis定义了路径,调用地址后需拼接自定义路径。如:“{在线服务的调用地址}/predictions/poetry”。 图5 获取API的接口地址
  • 方式一:使用Python语言通过AppKey+AppSecret认证鉴权方式发送预测请求 下载Python SDK并在开发工具中完成SDK配置。具体操作请参见在Python环境中集成API请求签名的SDK。 创建请求体,进行预测请求。 输入为文件格式 # coding=utf-8 import requests import os from apig_sdk import signer if __name__ == '__main__': # Config url, ak, sk and file path. url = "在线服务的调用地址" # 认证用的app_key和app_secret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以app_key和app_secret保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_APP_KEY和HUAWEICLOUD_APP_SECRET。 app_key = os.environ["HUAWEICLOUD_APP_KEY"] app_secret= os.environ["HUAWEICLOUD_APP_SECRET"] file_path = "预测文件的本地路径" # Create request, set method, url, headers and body. method = 'POST' headers = {"x-sdk-content-sha256": "UNSIGNED-PAYLOAD"} request = signer.HttpRequest(method, url, headers) # Create sign, set the AK/SK to sign and authenticate the request. sig = signer.Signer() sig.Key = app_key sig.Secret = app_secret sig.Sign(request) # Send request files = {'images': open(file_path, 'rb')} resp = requests.request(request.method, request.scheme + "://" + request.host + request.uri, headers=request.headers, files=files) # Print result print(resp.status_code) print(resp.text) “files”参数的请求体样式为“files={"请求参数":("文件路径",文件内容,“文件类型”)}”,参数填写可以参考表1。 表1 files参数说明 参数 是否必填 说明 请求参数 是 在线服务输入参数名称。 文件路径 否 上传文件的路径。 文件内容 是 上传文件的内容。 文件类型 否 上传文件类型。当前支持以下类型: txt类型:text/plain jpg/jpeg类型:image/jpeg png类型:image/png 输入为文本格式(json类型) 读取本地预测文件并进行base64编码的请求体示例如下: # coding=utf-8 import base64 import json import os import requests from apig_sdk import signer if __name__ == '__main__': # Config url, ak, sk and file path. url = "在线服务的调用地址" # 认证用的app_key和app_secret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以app_key和app_secret保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_APP_KEY和HUAWEICLOUD_APP_SECRET。 app_key = os.environ["HUAWEICLOUD_APP_KEY"] app_secret= os.environ["HUAWEICLOUD_APP_SECRET"] file_path = "预测文件的本地路径" with open(file_path, "rb") as file: base64_data = base64.b64encode(file.read()).decode("utf-8") # Create request, set method, url, headers and body. method = 'POST' headers = { 'Content-Type': 'application/json' } body = { 'image': base64_data } request = signer.HttpRequest(method, url, headers, json.dumps(body)) # Create sign, set the AppKey&AppSecret to sign and authenticate the request. sig = signer.Signer() sig.Key = app_key sig.Secret = app_secret sig.Sign(request) # Send request resp = requests.request(request.method, request.scheme + "://" + request.host + request.uri, headers=request.headers, data=request.body) # Print result print(resp.status_code) print(resp.text) “body”中的参数名由在线服务的输入参数决定,需要和“类型”为“string”的输入参数“名称”保持一致。此处以“image”为例。“body”中的base64_data值为string类型。
  • 方式二:使用Java语言发送预测请求 下载Java SDK并在开发工具中完成SDK配置。具体操作请参见在Java环境中集成API请求签名的SDK 创建Java类,进行预测请求。 由于在APIG的Java SDK中,“request.setBody()”只支持String类型,所以只支持输入为文本格式的预测请求。如果输入的是文件格式,需要先进行base64编码转换成文本。 输入为文件格式 此处以json格式为例介绍读取本地预测文件并进行base64编码的请求体,请求体示例如下: package com.apig.sdk.demo; import com.cloud.apigateway.sdk.utils.Client; import com.cloud.apigateway.sdk.utils.Request; import org.apache.commons.codec.binary.Base64; import org.apache.http.HttpHeaders; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class MyAkSkTest2 { public static void main(String[] args) { String url = "在线服务的调用地址"; // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 String ak = System.getenv("HUAWEICLOUD_SDK_AK"); String sk = System.getenv("HUAWEICLOUD_SDK_SK"); String filePath = "预测文件的本地路径"; try { // Create request Request request = new Request(); // Set the AK/SK to sign and authenticate the request. request.setKey(ak); request.setSecret(sk); // Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH. request.setMethod(HttpPost.METHOD_NAME); // Add header parameters request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); // Set a request URL in the format of https://{Endpoint}/{URI}. request.setUrl(url); // build your json body String body = "{\"image\":\"" + getBase64FromFile(filePath) + "\"}"; // Special characters, such as the double quotation mark ("), contained in the body must be escaped. request.setBody(body); // Sign the request. HttpRequestBase signedRequest = Client.sign(request); // Send request. CloseableHttpResponse response = HttpClients.createDefault().execute(signedRequest); // Print result System.out.println(response.getStatusLine().getStatusCode()); System.out.println(EntityUtils.toString(response.getEntity())); } catch (Exception e) { e.printStackTrace(); } } /** * Convert the file into a byte array and Base64 encode it * @return */ private static String getBase64FromFile(String filePath) { // Convert the file into a byte array InputStream in = null; byte[] data = null; try { in = new FileInputStream(filePath); data = new byte[in.available()]; in.read(data); in.close(); } catch (IOException e) { e.printStackTrace(); } // Base64 encode return new String(Base64.encodeBase64(data)); } } 使用base64编码方式,需要在模型推理代码中增加对请求体解码的代码。 输入为文本格式(json类型) // Package name of the demo. package com.apig.sdk.demo; import com.cloud.apigateway.sdk.utils.Client; import com.cloud.apigateway.sdk.utils.Request; import org.apache.http.HttpHeaders; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class MyAkSkTest { public static void main(String[] args) { String url = "在线服务的调用地址"; // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 String ak = System.getenv("HUAWEICLOUD_SDK_AK"); String sk = System.getenv("HUAWEICLOUD_SDK_SK"); try { // Create request Request request = new Request(); // Set the AK/SK to sign and authenticate the request. request.setKey(ak); request.setSecret(sk); // Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH. request.setMethod(HttpPost.METHOD_NAME); // Add header parameters request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); // Set a request URL in the format of https://{Endpoint}/{URI}. request.setUrl(url); // Special characters, such as the double quotation mark ("), contained in the body must be escaped. String body = "{}"; request.setBody(body); // Sign the request. HttpRequestBase signedRequest = Client.sign(request); // Send request. CloseableHttpResponse response = HttpClients.createDefault().execute(signedRequest); // Print result System.out.println(response.getStatusLine().getStatusCode()); System.out.println(EntityUtils.toString(response.getEntity())); } catch (Exception e) { e.printStackTrace(); } } } “body”由具体文本格式决定,此处以json为例。
  • 获取AK/SK 如果已生成过AK/SK,则可跳过此步骤,找到原来已下载的AK/SK文件,文件名一般为:credentials.csv。 如下图所示,文件包含了租户名(User Name),AK(Access Key Id),SK(Secret Access Key)。 图1 credential.csv文件内容 AK/SK生成步骤: 注册并登录管理控制台。 单击右上角的用户名,在下拉列表中单击“我的凭证”。 单击“访问密钥”。 单击“新增访问密钥”,进入“身份验证”页面。 根据提示完成身份验证,下载密钥,并妥善保管。
  • 方式一:使用Python语言发送预测请求 下载Python SDK并在开发工具中完成SDK配置。具体操作请参见在Python环境中集成API请求签名的SDK。 创建请求体,进行预测请求。 输入为文件格式 # coding=utf-8 import requests import os from apig_sdk import signer if __name__ == '__main__': # Config url, ak, sk and file path. url = "在线服务的调用地址" # 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 ak = os.environ["HUAWEICLOUD_SDK_AK"] sk = os.environ["HUAWEICLOUD_SDK_SK"] file_path = "预测文件的本地路径" # Create request, set method, url, headers and body. method = 'POST' headers = {"x-sdk-content-sha256": "UNSIGNED-PAYLOAD"} request = signer.HttpRequest(method, url, headers) # Create sign, set the AK/SK to sign and authenticate the request. sig = signer.Signer() sig.Key = ak sig.Secret = sk sig.Sign(request) # Send request files = {'images': open(file_path, 'rb')} resp = requests.request(request.method, request.scheme + "://" + request.host + request.uri, headers=request.headers, files=files) # Print result print(resp.status_code) print(resp.text) “file_path”为预测文件的本地路径,既可使用绝对路径(如Windows格式"D:/test.png",Linux格式"/opt/data/test.png"),也可以使用相对路径(如"./test.png")。 “files”参数的请求体样式为“files={"请求参数":("文件路径",文件内容,“文件类型”)}”,参数填写可以参考表1。 表1 files参数说明 参数 是否必填 说明 请求参数 是 在线服务输入参数名称。 文件路径 否 上传文件的路径。 文件内容 是 上传文件的内容。 文件类型 否 上传文件类型。当前支持以下类型: txt类型:text/plain jpg/jpeg类型:image/jpeg png类型:image/png 输入为文本格式(json类型) 读取本地预测文件并进行base64编码的请求体示例如下: # coding=utf-8 import base64 import json import os import requests from apig_sdk import signer if __name__ == '__main__': # Config url, ak, sk and file path. url = "在线服务的调用地址" # 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; # 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 ak = os.environ["HUAWEICLOUD_SDK_AK"] sk = os.environ["HUAWEICLOUD_SDK_SK"] file_path = "预测文件的本地路径" with open(file_path, "rb") as file: base64_data = base64.b64encode(file.read()).decode("utf-8") # Create request, set method, url, headers and body. method = 'POST' headers = { 'Content-Type': 'application/json' } body = { 'image': base64_data } request = signer.HttpRequest(method, url, headers, json.dumps(body)) # Create sign, set the AK/SK to sign and authenticate the request. sig = signer.Signer() sig.Key = ak sig.Secret = sk sig.Sign(request) # Send request resp = requests.request(request.method, request.scheme + "://" + request.host + request.uri, headers=request.headers, data=request.body) # Print result print(resp.status_code) print(resp.text) “body”中的参数名由在线服务的输入参数决定,需要和“类型”为“string”的输入参数“名称”保持一致。此处以“image”为例。“body”中的base64_data值为string类型。
共100000条