现象

  • 以 fastapi 为 web 框架,使用 langchain 调用大语言模型流式返回数据给web接口调用时,流式返回不能正常工作,只能整块返回

    return StreamingResponse(run(), media_type="text/event-stream")
  • 技术栈

    Python    3.11.8
    fastapi   0.111.1
    langchain 0.2.14
  • 有个奇怪的点是,这个问题在 Ubuntu(20.04/22.04) 上存在,在 Windows 10 上不存在

解决方法

  • 查了很多资料都是说,在 yield 后睡一会儿

    await asyncio.sleep(0.001)
  • 这个方案确实有效,但不是 qbit 想要的
  • 后面反复试验,找到了解决方法
  • 将 langchain 的调用改为异步

    # stream 改为 astream
    # for 改为 async for
    # 由
    for data in chain.stream(...):
      yield f"data:{data}\n\n" 
    # 改为
    async for data in chain.astream(...):
      yield f"data:{data}\n\n" 
  • 中途以为是 Linux 的 tcp buffer 太大,修改相关设置对这个问题无效

    sudo sysctl -w net.ipv4.tcp_wmem="1 1 1"

后记

  • qbit 发现 asyncio.sleep(0) 也是有效果的
  • 虽然官方文档GZipMiddleware 同时支持标准 response 和流式 response,但 qbit 使用中发现 GZipMiddlewareStreamingResponse 结合使用时有问题
    image.png

相关文献

本文出自 qbit snap

qbit
268 声望279 粉丝