python使用StreamingResponse进行流式传输,一直出现socket.send() raised exception,该怎么解决?

python使用StreamingResponse进行流式传输,一直出现socket.send() raised exception,该怎么解决?

问题描述

在python环境下使用fastAPI编写了一个流式响应的接口,在多次调接口的时候后台会不断报错socket.send() raised exception,一直循环报错,导致接口无法使用。

问题出现的环境背景及自己尝试过哪些方法

尝试过加错误处理检查是否与客户端连接断开,但问题仍然存在。

问chatGPT说
在使用 asyncio 进行流式传输时可能遇到的一个问题,即在发送大量数据或者在短时间内建立新的连接时,可能会触发一个无限循环的异常。

如何能在发生这个错误时使得服务能继续使用,或者这个错误是什么导致的呢该如何解决?

完整api代码

app = FastAPI()

app.add_middleware(

CORSMiddleware,

allow_origins=['*'],

allow_credentials=True,

allow_methods=['*'],

allow_headers=['*'],

)

class Message(BaseModel):

role: str

content: str

class ChatBody(BaseModel):

messages: List[Message]

model: str

stream: Optional[bool] = True

max_tokens: Optional[int]

temperature: Optional[float]

top_p: Optional[float]

@app.post("/v1/chat/completions")

async def completions(body: ChatBody, request: Request, background_tasks: BackgroundTasks):

background_tasks.add_task(torch_gc)

question = body.messages[-1]

if question.role == 'user':

question = question.content

else:

raise HTTPException(status.HTTP_400_BAD_REQUEST, "No Question Found")

history = []

user_question = ''

for message in body.messages:

if message.role == 'system':

history.append((message.content, "OK"))

if message.role == 'user':

user_question = message.content

elif message.role == 'assistant':

assistant_answer = message.content

history.append((user_question, assistant_answer))

if body.stream:

async def eval_llm():

first = True

for response in context.model.do_chat_stream(

context.model, context.tokenizer, question, history, {

"temperature": body.temperature,

"top_p": body.top_p,

"max_tokens": body.max_tokens,

}):

try:

yield response

except BrokenPipeError as e:

print(f"Client disconnected: {e}")

break

except Exception as e:

print(f"An exception occurred while sending data: {e}")

break

return StreamingResponse(

eval_llm(),

media_type="text/plain",

headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},

)

do_chat_stream函数代码

def do_chat_stream(model, tokenizer, question, history, model_args = None):

model_args = init_model_args(model_args)

sends = 0

#根据question和history计算聊天回答,循环迭代模型的输出每次迭代获取回答sends变量记录已发送的回答长度

for response, _ in model.stream_chat(

tokenizer, question, history,

temperature=model_args['temperature'],

top_p=model_args['top_p'],

max_length=max(2048, model_args['max_tokens'])):

ret = response[sends:]

# 修复表情符号的输出问题

if "\uFFFD" == ret[-1:]:

continue

sends = len(response)

yield ret

你期待的结果是什么?实际看到的错误信息又是什么?

报错信息:
socket.send() raised exception.
socket.send() raised exception.
socket.send() raised exception.
socket.send() raised exception.
socket.send() raised exception.
socket.send() raised exception.
socket.send() raised exception.
socket.send() raised exception.


回答:

多加一些异常捕获,看看哪里的问题

if body.stream:

async def eval_llm():

first = True

for response in context.model.do_chat_stream(

context.model, context.tokenizer, question, history, {

"temperature": body.temperature,

"top_p": body.top_p,

"max_tokens": body.max_tokens,

}):

try:

yield response

except (BrokenPipeError, ConnectionResetError) as e:

print(f"Client disconnected: {e}")

break

except Exception as e:

print(f"An exception occurred while sending data: {e}")

break

return StreamingResponse(

eval_llm(),

media_type="text/plain",

headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},

)

以上是 python使用StreamingResponse进行流式传输,一直出现socket.send() raised exception,该怎么解决? 的全部内容, 来源链接: utcz.com/p/938892.html

回到顶部