本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon SageMaker AI 模型的有状态会话
向 Amazon SageMaker AI 推理端点发送请求时,您可以选择将请求路由到有状态会话。在有状态会话期间,您会向同一个 ML 实例发送多个推理请求,而该实例会促进会话的进行。
通常,当您调用推理端点时,Amazon SageMaker AI 会将您的请求路由到端点所托管的多个实例中的任意一个 ML 实例。这种路由行为通过均匀分配推理流量,有助于最大限度地减少延迟。不过,路由行为的一个结果是,您无法预测哪个实例将为您的请求提供服务。
如果您打算将请求发送到有状态模型,那么这种不可预测性就是一种限制。有状态模型有一个容器,用于缓存从推理请求中接收到的上下文数据。由于数据是缓存的,因此您可以通过发送多个请求与容器进行交互,而在每个请求中,您都不需要包含交互的完整上下文。相反,该模型从缓存的上下文数据中获取预测信息。
当交互的上下文数据非常庞大时,例如包括以下内容时,有状态模型是理想的选择:
-
大型文本文件
-
冗长的聊天记录
-
用于多模态模型的多媒体数据(映像、视频和音频)
在这种情况下,如果每次提示都传递完整的上下文,请求的网络延迟就会减慢,应用程序的响应速度也会降低。
在推理端点支持有状态会话之前,它必须托管一个有状态模型。有状态模型的实施由您自己掌握。Amazon SageMaker AI 可让您将请求路由到有状态会话,但不提供可部署和使用的有状态模型。
有关演示如何实现有状态交互的笔记本和模型容器示例,请参阅 实施示例。
有关使用 TorchServe 实现有状态模型的信息,请参阅 TorchServe GitHub 存储库中的有状态推理
有状态会话如何工作
在有状态会话期间,应用程序通过以下方式与模型容器交互。
启动有状态会话
-
要使用 Amazon SageMaker AI 托管的有状态模型启动会话,客户端需要使用 SageMaker API 发送
InvokeEndpoint请求。对于SessionID请求参数,客户端通过指定NEW_SESSION值来告诉 SageMaker AI 启动一个新会话。在请求有效载荷中,客户端还会告诉容器启动一个新会话。该语句的语法因容器实现而异。这取决于容器代码如何处理请求有效载荷。下面的示例使用 Python SDK (Boto3) 启动了一个新会话:
import boto3 import sagemaker import json payload = { "requestType":"NEW_SESSION" } payload = json.dumps(payload) smr = boto3.client( 'sagemaker-runtime', region_name="region_name", endpoint_url="endoint_url") create_session_response = smr.invoke_endpoint( EndpointName="endpoint_name", Body=payload, ContentType="application/json", SessionId="NEW_SESSION") -
您的模型容器会通过启动一个新会话来处理客户的请求。对于会话,它会缓存客户端在请求有效载荷中发送的数据。它还会创建会话 ID,并设置生存时间(TTL)时间戳。该时间戳表示会话过期时间。容器必须通过在响应中设置以下 HTTP 标头,向 Amazon SageMaker AI 提供会话 ID 和时间戳:
X-Amzn-SageMaker-Session-Id:session_id; Expires=yyyy-mm-ddThh:mm:ssZ -
在对
InvokeEndpoint请求的响应中,Amazon SageMaker AI 会为NewSessionID响应参数提供会话 ID 和 TTL 时间戳。下面的示例将从
invoke_endpoint响应中提取会话 ID:session_id = create_session_response['ResponseMetadata']['HTTPHeaders']['x-amzn-sagemaker-new-session-id'].split(';')[0]
继续有状态会话
-
要在后续推理请求中使用同一会话,客户端需要发送另一个
InvokeEndpoint请求。对于SessionID请求参数,它指定了会话的 ID。有了这个 ID,SageMaker AI 就会将请求路由到在其中启动会话的同一个 ML 实例。由于容器已经缓存了原始请求有效载荷,因此客户端无需再传递与原始请求相同的上下文数据。下面的示例通过
SessionId请求参数传递会话 ID 来继续会话:smr.invoke_endpoint( EndpointName="endpoint_name", Body=payload, ContentType="application/json", SessionId=session_id)
关闭有状态会话
-
要关闭会话,客户端会发送最后一个
InvokeEndpoint请求。对于SessionID请求参数,客户端会提供会话 ID。在请求正文的有效负载中,客户机指出容器应关闭会话。该语句的语法因容器实现而异。下面的示例关闭了一个会话:
payload = { "requestType":"CLOSE" } payload = json.dumps(payload) closeSessionResponse = smr.invoke_endpoint( EndpointName="endpoint_name", Body=payload, ContentType="application/json", SessionId=session_id) -
当它关闭会话时,容器会通过在响应中设置以下 HTTP 标头将会话 ID 返回给 SageMaker AI:
X-Amzn-SageMaker-Closed-Session-Id:session_id -
在响应来自客户端的
InvokeEndpoint请求时,SageMaker AI 会为ClosedSessionId响应参数提供会话 ID。下面的示例将从
invoke_endpoint响应中提取已关闭的会话 ID:closed_session_id = closeSessionResponse['ResponseMetadata']['HTTPHeaders']['x-amzn-sagemaker-closed-session-id'].split(';')[0]
实施示例
下面的笔记本示例演示了如何为有状态模型实现容器。它还演示了客户端应用程序如何启动、继续和关闭有状态会话。
LLaVA stateful inference with SageMaker AI
该笔记本使用 LLaVA:大型语言和视觉助手