You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LangChain流式输出RAG响应时CPU占用率飙升至100%的优化求助

LangChain RAG流式输出CPU占用率过高的优化方案

问题现象

使用LangChain构建RAG系统,基于OpenAI API生成响应时,非流式输出场景CPU占用率正常,但启用流式输出后CPU会骤升至100%,具体代码及运行数据如下:

非流式输出代码

chat_history = []

question = input("Enter")
log_cpu_usage("Before Processing")
ai_msg = rag_chain.invoke({"question": question, "chat_history": chat_history})
print(ai_msg)
log_cpu_usage("After Processing")
chat_history.extend([HumanMessage(content = question), AIMessage(content=ai_msg)])

非流式输出结果

[CPU Usage] Before Processing: 14.3%
User: Hi
Hello Faiq! How can I assist you today?
[CPU Usage] After Processing: 16.8%
[CPU Usage] Before Processing: 13.6%
User: How are you?
Thank you for asking, Faiq! As an AI, I don't have feelings, but I'm here and ready to help you with any questions or concerns you may have. How can I assist you today?
[CPU Usage] After Processing: 2.5%
[CPU Usage] Before Processing: 11.4%

流式输出代码

chat_history = []

question = input("Enter")
answer = ""
for chunk in rag_chain.stream({"question":question, "chat_history": chat_history}):
    (chunk, end="", flush=True)  # 存在语法错误,应为print语句
    log_cpu_usage(":")
    answer +=chunk
    chat_history.extend([HumanMessage(content = question), AIMessage(content=answer)])

流式输出结果

[CPU Usage] CPU Usage:: 13.5%
User: Hi
[CPU Usage] :: 10.4%
Hello[CPU Usage] :: 0.0%
 F[CPU Usage] :: 100.0%
ai[CPU Usage] :: 100.0%
q[CPU Usage] :: 16.7%
![CPU Usage] :: 100.0%
 How[CPU Usage] :: 100.0%
 can[CPU Usage] :: 4.8%
 I[CPU Usage] :: 100.0%
 assist[CPU Usage] :: 0.0%
 you[CPU Usage] :: 16.7%
 today[CPU Usage] :: 100.0%
?[CPU Usage] :: 100.0%
[CPU Usage] :: 0.0%

优化方案

1. 移除循环内无效的chat_history更新

流式循环中逐chunk更新chat_history是完全冗余且错误的操作,会导致chat_history快速膨胀,且每次循环都创建HumanMessage和AIMessage对象,带来额外CPU开销。正确做法是等待整个回答生成完成后,再一次性更新chat_history。

2. 修复print语句语法错误

原代码中(chunk, end="", flush=True)是无效表达式,应改为print(chunk, end="", flush=True)。若对实时性要求不是极端苛刻,可减少flush频率(比如每3-5个chunk执行一次flush),降低IO操作带来的CPU消耗。

3. 降低CPU采样频率

每个chunk都调用log_cpu_usage会触发频繁的系统调用,额外消耗CPU资源。可设置时间间隔采样,比如每1秒记录一次:

import time

last_log_time = time.time()
log_interval = 1  # 采样间隔1秒

for chunk in rag_chain.stream({"question":question, "chat_history": chat_history}):
    print(chunk, end="", flush=True)
    current_time = time.time()
    if current_time - last_log_time >= log_interval:
        log_cpu_usage(":")
        last_log_time = current_time

4. 优化字符串拼接方式

频繁执行answer += chunk会产生多次内存分配和拷贝开销,改用列表收集chunk后一次性join,能显著降低CPU消耗:

answer_chunks = []
for chunk in rag_chain.stream({"question":question, "chat_history": chat_history}):
    print(chunk, end="", flush=True)
    answer_chunks.append(chunk)
answer = ''.join(answer_chunks)
# 回答生成完成后再更新chat_history
chat_history.extend([HumanMessage(content=question), AIMessage(content=answer)])

5. 确认LangChain链的流式逻辑

检查rag_chain结构,确保检索阶段仅执行一次,而非每个chunk都重复检索文档。例如使用RetrievalQA链时,检索操作应在stream调用前完成,流式仅作用于LLM的生成阶段,可通过添加日志确认检索是否重复执行。

6. 调整LLM流式输出的chunk大小

若LLM支持,可设置max_tokens_per_chunk参数,减少chunk的生成数量,从而降低循环迭代的次数,减少CPU上下文切换开销。

内容的提问来源于stack exchange,提问作者Faiq Aslam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:25:00