pytorch 在TorchServe上对随机请求进行极其缓慢的Bert推理

xdnvmnnf  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(184)

我已经通过TorchServe在AWS EC2 GPU示例上部署了Bert Hugging Face模型。配置了足够的资源,所有资源的使用率始终低于50%。
TorchServe在Bert模型上执行推理的速度很快,大部分时间低于50 ms。但是有时候它需要很长的时间,有时候,1-10秒,有几次甚至是120秒,当它在TorchServe本身超时时!有趣的是,当负载很高时,这种情况永远不会发生,但是当请求很少时。
我已经确定了需要很长时间或超时的请求,并重新运行了它们。除了没有问题,TorchServe在50 ms内响应。
我曾尝试通过k6在本地安装程序上使用长时间运行的测试脚本复制该问题,但没有效果。这种行为似乎不会在本地发生。
我唯一能想到的就是我正在使用Pytorch .jit模型,并将它们加载到TorchServe中。我以前遇到过.jit的性能问题,并将分析模式和执行器设置为False,解决了这些问题。这可能是连接。

self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Load TorchScript model
torch._C._jit_set_profiling_mode(False)
torch._C._jit_set_profiling_executor(False)
self.model = torch.jit.load(serialized_file)
self.model.eval()


# Using "@torch.no_grad()" decorator for python methods which call torch model

附上一些TorchServe访问日志以及Grafana屏幕截图以供说明。

2022-10-28T11:40:15,240 [INFO ] W-9004-A_categorization_1.4 ACCESS_LOG - /<some IP address>:<some_port> "POST /predictions/A_categorization HTTP/1.1" 200 43
2022-10-28T11:40:15,246 [INFO ] W-9005-A_text_quality_1.4 ACCESS_LOG - /<some IP address>:<some_port> "POST /predictions/A_text_quality HTTP/1.1" 200 39
2022-10-28T11:41:04,114 [INFO ] W-9004-B_categorization_1.4 ACCESS_LOG - /<some IP address>:<some_port> "POST /predictions/B_categorization HTTP/1.1" 200 51
2022-10-28T11:41:04,119 [INFO ] W-9005-B_text_quality_1.4 ACCESS_LOG - /<some IP address>:<some_port> "POST /predictions/B_text_quality HTTP/1.1" 200 43

2022-10-28T11:39:16,713 [INFO ] W-9004-A_categorization_1.4 ACCESS_LOG - /<some IP address>:<some_port> "POST /predictions/A_categorization HTTP/1.1" 200 1032
2022-10-28T11:39:23,465 [INFO ] W-9005-A_text_quality_1.4 ACCESS_LOG - /<some IP address>:<some_port> "POST /predictions/A_text_quality HTTP/1.1" 200 7784

其他项目信息:
Nvidia-smi:

NVIDIA-SMI 470.57.02    
Driver Version: 470.57.02    
CUDA Version: 11.4

Docker镜像:

pytorch/torchserve:0.6.0-gpu

PIP要求:

torch==1.9.1
transformers==3.1.0
pydantic==1.9.1
boto3==1.24.8
loguru==0.6.0
APScheduler==3.9.1

Torch 服务config.properties:

load_models=all
async_logging=true

models={\
  "categorization": {\
    "1.4": {\
        "defaultVersion": true,\
        "marName": "categorization.mar",\
        "minWorkers": 1,\
        "maxWorkers": 1,\
        "batchSize": 1,\
        "maxBatchDelay": 100\
    }\
  },\
  "text_quality": {\
    "1.4": {\
        "defaultVersion": true,\
        "marName": "text_quality.mar",\
        "minWorkers": 1,\
        "maxWorkers": 1,\
        "batchSize": 1,\
        "maxBatchDelay": 100\
    }\
  }\
}

此外,如何关闭TorchServe运行状况检查的日志记录?

pcww981p

pcww981p1#

问题是一个非常长的请求(~1.5MB的文本),令牌化器处理了超过120秒。该工作人员因超过120秒(这是默认值)未能响应健康检查而被TorchServe杀死。很难检测为什么工作器会死亡,因为正常文本长度的请求也会失败,直到一个新的工作器重新上线,给人的印象是TS没有好的理由失败。当我们将Sentry集成到我们的微服务架构中时,我们终于抓住了这个长请求。

解决方案:我们通过将文本长度限制为每个字段最多10,000个字符,减少了worker的处理时间。在我们的情况下,这仍然给出了良好的结果。在实施此解决方案之前,请检查这一点是否正确。

def limit_string_length(text: str, max_length: int = 10000) -> str:
    return text[:max_length]

另一个误导是tokenizer max_length属性。

encoding = self.tokenizer.encode_plus(
    f"{request.title} {request.description}",
    add_special_tokens=True,
    max_length=160,
    return_token_type_ids=False,
    return_attention_mask=True,
    return_tensors="pt",
    truncation=True,
)

我们将其设置为160,错误地认为它会在令牌化请求之前限制文本的最大长度。事实并非如此。标记器首先标记所有文本,然后将输出限制为160个字符。

相关问题