【问题标题】:Failed ping healthcheck after deploying TF2.1 model with TF-serving-container on AWS Sagemaker在 AWS Sagemaker 上使用 TF-serving-container 部署 TF2.1 模型后 ping 健康检查失败
【发布时间】:2020-10-29 22:33:15
【问题描述】:

我们希望将经过训练的 Tensorflow 模型部署到 AWS Sagemaker,以使用 tensorflow-serving-container 进行推理。 TensorFlow 版本是 2.1。按照https://github.com/aws/sagemaker-tensorflow-serving-container 的指南,已采取以下步骤:

  1. 构建 TF 2.1 AMI 并在本地测试成功后将其发布到 AWS ECR
  2. 为 S3 和 ECR 设置 Sagemaker 执行角色权限。
  3. 将保存的 TF 模型文件夹(saved_model.pb、资产、变量)打包到 model.tar.gz 中
  4. 使用实时预测器创建端点:
import os
import sagemaker
from sagemaker.tensorflow.serving import Model
from sagemaker.tensorflow.model import TensorFlowModel
from sagemaker.predictor import json_deserializer, json_serializer, RealTimePredictor
from sagemaker.content_types import CONTENT_TYPE_JSON

def create_tfs_sagemaker_model():
    sagemaker_session = sagemaker.Session()
    role = 'arn:aws:iam::XXXXXXXXX:role/service-role/AmazonSageMaker-ExecutionRole-XXXXXXX
    bucket = 'tf-serving'
    prefix = 'sagemaker/tfs-test'
    s3_path = 's3://{}/{}'.format(bucket, prefix)
    image = 'XXXXXXXX.dkr.ecr.eu-central-1.amazonaws.com/sagemaker-tensorflow-serving:2.1.0-cpu'
    model_data = sagemaker_session.upload_data('model.tar.gz', bucket, os.path.join(prefix, 'model'))
    endpoint_name = 'tf-serving-ep-test-1'
    tensorflow_serving_model = Model(model_data=model_data, role=role, sagemaker_session=sagemaker_session, image=image, framework_version='2.1')
    tensorflow_serving_model.deploy(initial_instance_count=1, instance_type='ml.c4.xlarge', endpoint_name=endpoint_name)
    rt_predictor = RealTimePredictor(endpoint=endpoint_name, sagemaker_session=sagemaker_session, serializer=json_serializer, content_type=CONTENT_TYPE_JSON, accept=CONTENT_TYPE_JSON)
  1. 创建批量转换作业:
def create_tfs_sagemaker_batch_transform():
    sagemaker_session = sagemaker.Session()
    print(sagemaker_session.boto_region_name)
    role = 'arn:aws:iam::XXXXXXXXXXX:role/service-role/AmazonSageMaker-ExecutionRole-XXXXXXXX'
    bucket = 'XXXXXXX-tf-serving'
    prefix = 'sagemaker/tfs-test'
    image = 'XXXXXXXXXX.dkr.ecr.eu-central-1.amazonaws.com/sagemaker-tensorflow-serving:2.1.0-cpu'
    s3_path = 's3://{}/{}'.format(bucket, prefix)
    model_data = sagemaker_session.upload_data('model.tar.gz', bucket, os.path.join(prefix, 'model'))
    tensorflow_serving_model = Model(model_data=model_data, role=role, sagemaker_session=sagemaker_session, image=image, name='deep-net-0', framework_version='2.1')
    print(tensorflow_serving_model.model_data)
    out_path = 's3://XXXXXX-serving-out/'
    input_path = "s3://XXXXXX-serving-in/"    
    tensorflow_serving_transformer = tensorflow_serving_model.transformer(instance_count=1, instance_type='ml.c4.xlarge', accept='application/json', output_path=out_path)
    tensorflow_serving_transformer.transform(input_path, content_type='application/json')

第 4 步和第 5 步都在运行,在 AWS Cloudwatch 日志中,我们看到实例成功启动、模型加载和 TF-Serving 进入事件循环 - 见下文:

2020-07-08T17:07:16.156+02:00 INFO:ma​​in:启动服务

2020-07-08T17:07:16.156+02:00 INFO:ma​​in:nginx 配置:

2020-07-08T17:07:16.156+02:00 load_module 模块/ngx_http_js_module.so;

2020-07-08T17:07:16.156+02:00 worker_processes 自动;

2020-07-08T17:07:16.156+02:00 守护进程关闭;

2020-07-08T17:07:16.156+02:00 pid /tmp/nginx.pid;

2020-07-08T17:07:16.157+02:00 error_log /dev/stderr 错误;

2020-07-08T17:07:16.157+02:00 worker_rlimit_nofile 4096;

2020-07-08T17:07:16.157+02:00 事件 { worker_connections 2048;

2020-07-08T17:07:16.157+02:00 }

2020-07-08T17:07:16.162+02:00 http { 包括 /etc/nginx/mime.types; default_type 应用程序/json; access_log /dev/stdout 结合; js_include tensorflow-serving.js;上游 tfs_upstream { 服务器 本地主机:10001; } 上游 gunicorn_upstream { 服务器 unix:/tmp/gunicorn.sock fail_timeout=1; } 服务器 { 听 8080 延期; client_max_body_size 0; client_body_buffer_size 100m; subrequest_output_buffer_size 100m;设置 $tfs_version 2.1;放 $default_tfs_model 无;位置 /tfs { 重写 ^/tfs/(.*) /$1 break; 代理重定向关闭; proxy_pass_request_headers 关闭; proxy_set_header 内容类型“应用程序/json”; proxy_set_header 接受 '应用程序/json'; proxy_pass http://tfs_upstream; } 位置 /ping { js_content 平; } 位置 /invocations { js_content 调用; } 位置 /models { proxy_pass http://gunicorn_upstream/models; } location / { return 404 '{"error": "Not Found"}'; } keepalive_timeout 3; }

2020-07-08T17:07:16.162+02:00 }

2020-07-08T17:07:16.162+02:00 INFO:tfs_utils:使用默认模型名称: 型号

2020-07-08T17:07:16.162+02:00 INFO:tfs_utils:tensorflow 服务模型 配置:

2020-07-08T17:07:16.162+02:00 模型配置列表:{配置:{名称: "model", base_path: "/opt/ml/model", model_platform: "tensorflow" }

2020-07-08T17:07:16.162+02:00 }

2020-07-08T17:07:16.162+02:00 INFO:ma​​in:使用默认型号名称: 型号

2020-07-08T17:07:16.162+02:00 INFO:ma​​in:tensorflow 服务模型 配置:

2020-07-08T17:07:16.163+02:00 模型配置列表:{配置:{名称: "model", base_path: "/opt/ml/model", model_platform: "tensorflow" }

2020-07-08T17:07:16.163+02:00 }

2020-07-08T17:07:16.163+02:00 INFO:ma​​in:tensorflow 版本信息:

2020-07-08T17:07:16.163+02:00 TensorFlow 模型服务器: 2.1.0-rc1+dev.sha.075ffcf

2020-07-08T17:07:16.163+02:00 TensorFlow 库:2.1.0

2020-07-08T17:07:16.163+02:00 INFO:ma​​in:tensorflow serving 命令:tensorflow_model_server --port=10000 --rest_api_port=10001 --model_config_file=/sagemaker/model-config.cfg --max_num_load_retries=0

2020-07-08T17:07:16.163+02:00 INFO:ma​​in:开始 tensorflow 服务 (pid: 13)

2020-07-08T17:07:16.163+02:00 INFO:ma​​in:nginx 版本信息:

2020-07-08T17:07:16.163+02:00 nginx版本:nginx/1.18.0

2020-07-08T17:07:16.163+02:00 由 gcc 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)

2020-07-08T17:07:16.163+02:00 使用 OpenSSL 1.1.1 构建,2018 年 9 月 11 日

2020-07-08T17:07:16.163+02:00 启用 TLS SNI 支持

2020-07-08T17:07:16.163+02:00 配置参数:--prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var /log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run /nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp- path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user= nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module -- with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --带邮件--带- mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx- 1.18.0/debian/debuild-base/nginx-1.18.0=。 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl, -z,now -Wl,--按需 -pie'

2020-07-08T17:07:16.163+02:00 INFO:ma​​in:启动 nginx (pid: 15)

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.075708: 我 tensorflow_serving/model_servers/server_core.cc:462] 添加/更新 模型。

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.075760: 我 tensorflow_serving/model_servers/server_core.cc:573](重新)添加 型号:型号

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.180755: 我 tensorflow_serving/util/retrier.cc:46] 重试预留资源 对于可服务:{name:模型版本:1} 已用尽 max_num_retries:0

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.180887: 我 tensorflow_serving/core/basic_manager.cc:739] 成功保留 加载可服务的资源{名称:模型版本:1}

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.180919: 我 tensorflow_serving/core/loader_harness.cc:66] 批准负载 可服务版本{名称:模型版本:1}

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.180944: 我 tensorflow_serving/core/loader_harness.cc:74] 加载可服务版本 {名称:型号版本:1}

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.180995: 我 外部/org_tensorflow/tensorflow/cc/saved_model/reader.cc:31] 从 /opt/ml/model/1 读取 SavedModel

2020-07-08T17:07:16.163+02:00 2020-07-08 15:07:15.205712: 我 外部/org_tensorflow/tensorflow/cc/saved_model/reader.cc:54] 阅读带有标签的元图 { serve }

2020-07-08T17:07:16.164+02:00 2020-07-08 15:07:15.205825: 我 外部/org_tensorflow/tensorflow/cc/saved_model/loader.cc:264] 从以下位置读取 SavedModel 调试信息(如果存在):/opt/ml/model/1

2020-07-08T17:07:16.164+02:00 2020-07-08 15:07:15.208599: 我 外部/org_tensorflow/tensorflow/core/common_runtime/process_util.cc:147] 使用默认互操作设置创建新线程池: 2. 调整使用 inter_op_parallelism_threads 以获得最佳性能。

2020-07-08T17:07:16.164+02:00 2020-07-08 15:07:15.328057: 我 外部/org_tensorflow/tensorflow/cc/saved_model/loader.cc:203] 正在恢复 SavedModel 包。

2020-07-08T17:07:17.165+02:00 2020-07-08 15:07:16.578796: 我 外部/org_tensorflow/tensorflow/cc/saved_model/loader.cc:152] 在路径上的 SavedModel 包上运行初始化操作: /opt/ml/model/1

2020-07-08T17:07:17.165+02:00 2020-07-08 15:07:16.626494: 我 外部/org_tensorflow/tensorflow/cc/saved_model/loader.cc:333] 标签 { serve } 的 SavedModel 加载;状态:成功:OK。拿了1445495 微秒。

2020-07-08T17:07:17.165+02:00 2020-07-08 15:07:16.630443: 我 tensorflow_serving/servables/tensorflow/saved_model_warmup.cc:105] 否 预热数据文件位于 /opt/ml/model/1/assets.extra/tf_serving_warmup_requests

2020-07-08T17:07:17.165+02:00 2020-07-08 15:07:16.632461: 我 tensorflow_serving/util/retrier.cc:46] 重试加载可服务: {name: model version: 1} 用尽 max_num_retries: 0

2020-07-08T17:07:17.165+02:00 2020-07-08 15:07:16.632484: 我 tensorflow_serving/core/loader_harness.cc:87] 成功加载 可服务版本{名称:模型版本:1}

2020-07-08T17:07:17.165+02:00 2020-07-08 15:07:16.634727: 我 tensorflow_serving/model_servers/server.cc:362] 运行 gRPC 模型服务器在 0.0.0.0:10000 ...

2020-07-08T17:07:17.165+02:00 [警告] getaddrinfo:地址族 不支持节点名

2020-07-08T17:07:17.165+02:00 2020-07-08 15:07:16.635747: 我 tensorflow_serving/model_servers/server.cc:382] 导出 HTTP/REST API 位于:localhost:10001 ...

2020-07-08T17:07:17.165+02:00 [evhttp_server.cc : 238] NET_LOG: 进入事件循环……

但是(端点和批量转换)都未能通过 Sagemaker Ping 运行状况检查:

2020-07-08T17:07:32.169+02:00 2020/07/08 15:07:31 [错误] 16#16: *1 js: ping 失败{ "error": "找不到任何版本的模型无" }

2020-07-08T17:07:32.170+02:00 169.254.255.130 - - [08/Jul/2020:15:07:31 +0000] "GET /ping HTTP/1.1" 502 157 "-" "Go-http-client/1.1"

另外,当使用自建的 docker tf-serving-container 在本地测试时,模型运行没有问题,可以使用 curl 进行查询。 可能是什么问题?

【问题讨论】:

    标签: amazon-web-services tensorflow machine-learning tensorflow-serving amazon-sagemaker


    【解决方案1】:

    问题的解决方法如下:

    环境变量“SAGEMAKER_TFS_DEFAULT_MODEL_NAME”需要设置为正确的模型名称,例如“模型”

    import os
    import sagemaker
    from sagemaker.tensorflow.serving import Model
    from sagemaker.tensorflow.model import TensorFlowModel
    from sagemaker.predictor import json_deserializer, json_serializer, RealTimePredictor
    from sagemaker.content_types import CONTENT_TYPE_JSON
    
    def create_tfs_sagemaker_model():
        sagemaker_session = sagemaker.Session()
        role = 'arn:aws:iam::XXXXXXXXX:role/service-role/AmazonSageMaker-ExecutionRole-XXXXXXX
        bucket = 'tf-serving'
        prefix = 'sagemaker/tfs-test'
        s3_path = 's3://{}/{}'.format(bucket, prefix)
        image = 'XXXXXXXX.dkr.ecr.eu-central-1.amazonaws.com/sagemaker-tensorflow-serving:2.1.0-cpu'
        model_data = sagemaker_session.upload_data('model.tar.gz', bucket, os.path.join(prefix, 'model'))
        endpoint_name = 'tf-serving-ep-test-1'
        env = {"SAGEMAKER_TFS_DEFAULT_MODEL_NAME": "model"}
        tensorflow_serving_model = Model(model_data=model_data, role=role, sagemaker_session=sagemaker_session, image=image, name='model', framework_version='2.1', env=env)
        tensorflow_serving_model.deploy(initial_instance_count=1, instance_type='ml.c4.xlarge', endpoint_name=endpoint_name)
        rt_predictor = RealTimePredictor(endpoint=endpoint_name, sagemaker_session=sagemaker_session, serializer=json_serializer, content_type=CONTENT_TYPE_JSON, accept=CONTENT_TYPE_JSON)
    

    这会正确创建端点并通过 ping 健康检查:

    2020-07-16T12:08:20.654+02:00 10.32.0.2 - - [16/Jul/2020:10:08:20 +0000] "GET /ping HTTP/1.1" 200 0 "-" "AHC/2.0"

    【讨论】:

      【解决方案2】:

      您的模型在日志中的前面似乎被命名为 "model" 到 TensorFlow Serving:

      2020-07-08T17:07:16.162+02:00 INFO:main:using default model name: model
      2020-07-08T17:07:16.162+02:00 INFO:main:tensorflow serving model config:
      

      但在错误中,ping 检查被路由到 TensorFlow Serving 作为名为:`"None" 的模型

      `Could not find any versions of model None`
      

      我不确定这个错误是由于 Docker 容器还是在 SageMaker 端发生的。但是……我确实发现了这个可疑的环境变量TFS_DEFAULT_MODEL_NAME,默认设置为"None":

      class PythonServiceResource:
      
          def __init__(self):
              if SAGEMAKER_MULTI_MODEL_ENABLED:
                  self._model_tfs_rest_port = {}
                  self._model_tfs_grpc_port = {}
                  self._model_tfs_pid = {}
                  self._tfs_ports = self._parse_sagemaker_port_range(SAGEMAKER_TFS_PORT_RANGE)
              else:
                  self._tfs_grpc_port = TFS_GRPC_PORT
                  self._tfs_rest_port = TFS_REST_PORT
      
              self._tfs_enable_batching = SAGEMAKER_BATCHING_ENABLED == 'true'
              self._tfs_default_model_name = os.environ.get('TFS_DEFAULT_MODEL_NAME', "None")
      

      您能否尝试在您的容器中设置TFS_DEFAULT_MODEL_NAME 看看会发生什么?

      如果这不起作用,您可能会更成功地在TensorFlow SageMaker container github 上发布错误。亚马逊专家会定期检查。

      顺便说一句,我很想谈谈您如何将 SageMaker 端点与 TensorFlow 模型一起用于我正在进行的一些研究。如果您愿意,请发送电子邮件至yoavz@modelzoo.dev。

      【讨论】:

      • 这可能是对的。但是在非 AWS TFS 容器的本地构建过程中,我将磁盘上的本地模型绑定到服务器,它负责正确绑定。这使得测试期间的模型交换变得容易。对于生产,最终模型将集成到容器本身中。我希望 AWS-TFS 具有相同的行为,其中 Sagemaker Image 将 S3 中的模型绑定到容器。我也尝试设置模型名称,但没有成功。那么在这个过程中的某个地方,模型名称会丢失吗?我将使用来自 aws-github 的标准示例对其进行测试,以检查它是否有效。
      猜你喜欢
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      • 2019-03-05
      • 2015-01-23
      相关资源
      最近更新 更多