chatchat-space / Langchain-Chatchat

Langchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM, Qwen 与 Llama 等语言模型的 RAG 与 Agent 应用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain
Apache License 2.0
31.08k stars 5.42k forks source link

求教怎样多进程或多线程启动AI服务接口 #4559

Closed Longleaves closed 2 weeks ago

Longleaves commented 1 month ago

发现python starup.py -a后,当多个人同时提问AI模型时,输出会卡顿,速度较慢。运行的是13b模型。 硬件占用情况: 1.显卡占用为一半不到(2张48G显卡,分别只占用了20G不到) 2.cpu占用率仅为2个核(220%),现在cpu为16核,怎么利用上其他核?

想求教各位大佬,怎样可以多进程或多线程启动AI服务接口,应该是端口7861。 是应该改写starup.py中的run_model_worker的uvicorn.run(app, host=host, port=port, log_level=log_level.lower()) 吗? starup.py参数改了如下部分: args.gpus = "0,1" # GPU的编号,如果有多个GPU,可以设置为"0,1,2,3" args.max_gpu_memory = "40GiB" args.num_gpus = 2 # model worker的切分是model并行,这里填写显卡的数量

我才疏学浅,真挚请教各位,谢谢!

SwordHG commented 1 month ago

+1 有心人来解答下 运行的是0.2.10版本,并发请求knowledge_base_chat接口 看日志是顺序执行 image

zqt996 commented 1 month ago

@Longleaves 什么版本

zqt996 commented 1 month ago

@SwordHG 3版本支持并发

Longleaves commented 1 month ago

@Longleaves 什么版本

谢谢,版本是0.2.10 想请教一下3版本直接就是并发吗,进程数或者线程数在哪里修改呀?

SwordHG commented 1 month ago

@zqt996 0.2.10版本如果要修改成并发的是否有什么建议

zqt996 commented 1 month ago

2版本的话地自己写,线程池呗最简单,或者挂后台任务也行

zqt996 commented 1 month ago

@SwordHG

zqt996 commented 1 month ago

@Longleaves 什么版本

谢谢,版本是0.2.10 想请教一下3版本直接就是并发吗,进程数或者线程数在哪里修改呀?

是的3版本是用的多线程

Longleaves commented 1 month ago

@Longleaves 什么版本

谢谢,版本是0.2.10 想请教一下3版本直接就是并发吗,进程数或者线程数在哪里修改呀?

是的3版本是用的多线程

谢谢,可以问下3版本在哪修改线程数吗? @zqt996 @liunux4odoo

zqt996 commented 1 month ago

@Longleaves 哪你地改下代码 Langchain-Chatchat\libs\chatchat-server\chatchat\server\utils.py with ThreadPoolExecutor() as pool:我之后会改成后台task支持分布式和单机模式

Crescentz commented 1 month ago

诚心请教下 0.2.10 版本怎么修改并发

zqt996 commented 1 month ago

@Crescentz 参考3

Longleaves commented 1 month ago

with ThreadPoolExecutor()

@zqt996 谢谢!是以下这段代码吗,是改为什么样的呀? 我看好像主要是在读取文件的时候用,想问下AI接口7861也是可以通过这里实现多线程吗,请您再赐教,非常感谢!

tasks = []
with ThreadPoolExecutor() as pool:
    for kwargs in params:
        thread = pool.submit(func, **kwargs)
        tasks.append(thread)

    for obj in as_completed(tasks):
        yield obj.result()
Longleaves commented 1 month ago

@zRzRzRzRzRzRzR 可以请教一下您吗

Nancy7zt commented 1 month ago

我也想问这个问题,我在本地postman同时发送多个请求,仍然顺发执行

SwordHG commented 1 month ago

感觉是同一时间只能一个接口,其它都被挂起了

zqt996 commented 1 month ago

着急可以吧kb_doc_api.py 336行 改多线程或者协程试试 向量化这块在大改不一定啥时候改搞好

---- 回复的原邮件 ---- | 发件人 | @.> | | 日期 | 2024年07月24日 09:10 | | 收件人 | @.> | | 抄送至 | @.>@.> | | 主题 | Re: [chatchat-space/Langchain-Chatchat] 求教怎样多进程或多线程启动AI服务接口 (Issue #4559) |

感觉是同一时间只能一个接口,其它都被挂起了

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

Longleaves commented 1 month ago

@Longleaves 哪你地改下代码 Langchain-Chatchat\libs\chatchat-server\chatchat\server\utils.py with ThreadPoolExecutor() as pool:我之后会改成后台task支持分布式和单机模式

@zqt996 您好,期待后面kb问答能多线程,现在想先请教下对话接口可以实现多线程吗,我试过将启动服务代码放到线程池里,但也无法接收多个请求,多俩人用就不行了,谢谢您的解答呀。

SwordHG commented 1 month ago

0.2.10版本正常的并发是可以的,其实不能叫并发,它就是异步,langchain框架应该是没有并发管理的,就是一个异步,所以导致,多个请求能请求,但是就是排队请求,同时请求量高的时候,整体的rt就是变长,所以要想实现真高并发,看来要不改框架,要么换框架,自己写了

SwordHG commented 1 month ago

0.3的版本应该一样,没有真的高并发

Nancy7zt commented 1 month ago

我在他的基础上套了个gunicorn 这个框架

---- 回复的原邮件 ---- | 发件人 | @.> | | 发送日期 | 2024年07月25日 15:19 | | 收件人 | chatchat-space/Langchain-Chatchat @.> | | 抄送人 | leozz77 @.>, Comment @.> | | 主题 | Re: [chatchat-space/Langchain-Chatchat] 求教怎样多进程或多线程启动AI服务接口 (Issue #4559) |

0.3的版本应该一样,没有真的高并发

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

SwordHG commented 1 month ago

我在他的基础上套了个gunicorn 这个框架 ---- 回复的原邮件 ---- | 发件人 | @.> | | 发送日期 | 2024年07月25日 15:19 | | 收件人 | chatchat-space/Langchain-Chatchat @.> | | 抄送人 | leozz77 @.>, Comment @.> | | 主题 | Re: [chatchat-space/Langchain-Chatchat] 求教怎样多进程或多线程启动AI服务接口 (Issue #4559) | 0.3的版本应该一样,没有真的高并发 — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

效果如何?是否可以分享下代码?

Longleaves commented 1 month ago

我在他的基础上套了个gunicorn 这个框架

@Nancy7zt 同求,可否请大佬分享一下。

Nancy7zt commented 1 month ago

我是小白,我只是加了个框架,不知道效果如何 def run_api_server(started_event: mp.Event = None, run_mode: str = None): from server.api import create_app from server.utils import set_httpx_config

set_httpx_config()

app = create_app(run_mode=run_mode)
_set_app_event(app, started_event)

host = API_SERVER["host"]
port = API_SERVER["port"]

# 确保应用程序可以被 Gunicorn 导入
os.environ["RUN_MODE"] = run_mode if run_mode else ""

# Gunicorn 命令
gunicorn_command = [
    "gunicorn",
    "server.api:create_app()",
    "-b", f"{host}:{port}",
    "-w", str(mp.cpu_count() * 2 + 1),
    "-k", "uvicorn.workers.UvicornWorker"
]

# 启动 Gunicorn
subprocess.run(gunicorn_command)

修改startup.py的run_api_server 函数 你们试下

Longleaves commented 1 month ago

我是小白,我只是加了个框架,不知道效果如何 def run_api_server(started_event: mp.Event = None, run_mode: str = None): from server.api import create_app from server.utils import set_httpx_config

set_httpx_config()

app = create_app(run_mode=run_mode)
_set_app_event(app, started_event)

host = API_SERVER["host"]
port = API_SERVER["port"]

# 确保应用程序可以被 Gunicorn 导入
os.environ["RUN_MODE"] = run_mode if run_mode else ""

# Gunicorn 命令
gunicorn_command = [
    "gunicorn",
    "server.api:create_app()",
    "-b", f"{host}:{port}",
    "-w", str(mp.cpu_count() * 2 + 1),
    "-k", "uvicorn.workers.UvicornWorker"
]

# 启动 Gunicorn
subprocess.run(gunicorn_command)

修改startup.py的run_api_server 函数 你们试下

@Nancy7zt 谢谢! 我按照上面的改了,好像无法正常启动呀?加载完模型就卡在这里了,web端口也没显示。您可以正常启动吗?

图片

SwordHG commented 1 month ago

我是小白,我只是加了个框架,不知道效果如何 def run_api_server(started_event: mp.Event = None, run_mode: str = None): from server.api import create_app from server.utils import set_httpx_config

set_httpx_config()

app = create_app(run_mode=run_mode)
_set_app_event(app, started_event)

host = API_SERVER["host"]
port = API_SERVER["port"]

# 确保应用程序可以被 Gunicorn 导入
os.environ["RUN_MODE"] = run_mode if run_mode else ""

# Gunicorn 命令
gunicorn_command = [
    "gunicorn",
    "server.api:create_app()",
    "-b", f"{host}:{port}",
    "-w", str(mp.cpu_count() * 2 + 1),
    "-k", "uvicorn.workers.UvicornWorker"
]

# 启动 Gunicorn
subprocess.run(gunicorn_command)

修改startup.py的run_api_server 函数 你们试下

@Nancy7zt 谢谢! 我按照上面的改了,好像无法正常启动呀?加载完模型就卡在这里了,web端口也没显示。您可以正常启动吗?

图片

就是同时启动多个进程,对内存需求大,你可以先-w的值小一点,直接改成2试试看,能不能起来

Longleaves commented 1 month ago

我是小白,我只是加了个框架,不知道效果如何 def run_api_server(started_event: mp.Event = None, run_mode: str = None): from server.api import create_app from server.utils import set_httpx_config

set_httpx_config()

app = create_app(run_mode=run_mode)
_set_app_event(app, started_event)

host = API_SERVER["host"]
port = API_SERVER["port"]

# 确保应用程序可以被 Gunicorn 导入
os.environ["RUN_MODE"] = run_mode if run_mode else ""

# Gunicorn 命令
gunicorn_command = [
    "gunicorn",
    "server.api:create_app()",
    "-b", f"{host}:{port}",
    "-w", str(mp.cpu_count() * 2 + 1),
    "-k", "uvicorn.workers.UvicornWorker"
]

# 启动 Gunicorn
subprocess.run(gunicorn_command)

修改startup.py的run_api_server 函数 你们试下

@Nancy7zt 谢谢! 我按照上面的改了,好像无法正常启动呀?加载完模型就卡在这里了,web端口也没显示。您可以正常启动吗? 图片

就是同时启动多个进程,对内存需求大,你可以先-w的值小一点,直接改成2试试看,能不能起来

@SwordHG 还是卡在那儿了

Nancy7zt commented 1 month ago

你看一下当前内存占用情况

Longleaves commented 1 month ago

你看一下当前内存占用情况

@Nancy7zt 内存还很空,您是可以正常启动运行的吗 图片

SwordHG commented 1 month ago

你看一下当前内存占用情况

@Nancy7zt 内存还很空,您是可以正常启动运行的吗 图片

要先pip insall gunicorn def run_api_server(started_event: mp.Event = None, run_mode: str = None): from server.api import create_app import uvicorn, gunicorn from server.utils import set_httpx_config set_httpx_config()

app = create_app(run_mode=run_mode)
_set_app_event(app, started_event)

host = API_SERVER["host"]
port = API_SERVER["port"]

# 确保应用程序可以被 Gunicorn 导入
os.environ["RUN_MODE"] = run_mode if run_mode else ""

# Gunicorn 命令
gunicorn_command = [
    "gunicorn",
    "server.api:app",
    "-b", f"{host}:{port}",
    "-w", str(3),
    "-k", "uvicorn.workers.UvicornWorker"
]

# 启动 Gunicorn
subprocess.run(gunicorn_command)

# uvicorn.run(app, host=host, port=port) 我代码,没出现问题,直接跑起来了,不知道你是不是oom,假如你本地加载embedding模型啥的"-w", str(3)这个千万要设置小一点,你gpu内存肯定不够的
Nancy7zt commented 1 month ago

不好意思,我也不知道如何处理了

Nancy7zt commented 1 month ago

你用只启用api的命令 试试 python startup.py --all-api

Longleaves commented 1 month ago

@SwordHG @Nancy7zt 谢谢你们!api可以启动了,但就不能同时启动网页端。二位网页端也能同时正常启动吗?

SwordHG commented 1 month ago

我放弃网页端了,只对7861这个端口进行请求

Nancy7zt commented 1 month ago

我这边只用请求这个api接口 streamlit 好像不支持并发,你得自己改

---- 回复的原邮件 ---- | 发件人 | @.> | | 发送日期 | 2024年07月25日 18:07 | | 收件人 | chatchat-space/Langchain-Chatchat @.> | | 抄送人 | leozz77 @.>, Mention @.> | | 主题 | Re: [chatchat-space/Langchain-Chatchat] 求教怎样多进程或多线程启动AI服务接口 (Issue #4559) |

我放弃网页端了,只对7861这个端口进行请求

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

Longleaves commented 1 month ago

@Nancy7zt @SwordHG 谢谢!我摸索一下,后续多交流。

zqt996 commented 1 month ago

@Longleaves 哪你地改下代码 Langchain-Chatchat\libs\chatchat-server\chatchat\server\utils.py with ThreadPoolExecutor() as pool:我之后会改成后台task支持分布式和单机模式

@zqt996 您好,期待后面kb问答能多线程,现在想先请教下对话接口可以实现多线程吗,我试过将启动服务代码放到线程池里,但也无法接收多个请求,多俩人用就不行了,谢谢您的解答呀。

你是不是配置不够

Longleaves commented 1 month ago

@Longleaves 哪你地改下代码 Langchain-Chatchat\libs\chatchat-server\chatchat\server\utils.py with ThreadPoolExecutor() as pool:我之后会改成后台task支持分布式和单机模式

@zqt996 您好,期待后面kb问答能多线程,现在想先请教下对话接口可以实现多线程吗,我试过将启动服务代码放到线程池里,但也无法接收多个请求,多俩人用就不行了,谢谢您的解答呀。

你是不是配置不够

@zqt996 谢谢,配置还没占满的,请问这个线程池是放在run_api_server里面吗,还是加在哪里。如果放在run_api_server会报错:

图片

改的代码如下: 图片

Nancy7zt commented 1 month ago

他说7861端口已经被占用了 你得把这个端口kill掉

Longleaves commented 1 month ago

@SwordHG @Nancy7zt 我发现用gunicorn,当多个人使用的时候还是会出现异步错误,而且gpu占用也没提高呀:

图片

Nancy7zt commented 1 month ago

这和gpu占用没关系吧。。。 你这个问题是有些东西没关闭 你执行目录下面的shutdown那个。你如果说和gpu占用有关系的话,那是并行推理了。。 我这个仅仅是对接口高并发

Longleaves commented 1 month ago

这和gpu占用没关系吧。。。 你这个问题是有些东西没关闭 你执行目录下面的shutdown那个。你如果说和gpu占用有关系的话,那是并行推理了。。 我这个仅仅是对接口高并发

谢谢,是/chat/chat接口的高并发吗?你那边测过并发量大概在多少呀,会出现上面的错误吗?我shutdown又重启了,测的时候报错这个。

Longleaves commented 1 month ago

@SwordHG @Nancy7zt 再打扰一下,大佬们测过并发量有没有提高呀

Nancy7zt commented 1 month ago

我这边是之前调用agent接口会一直宕机,但是我加了这个对接口高并发的操作后,就不会出现宕机的问题了

SwordHG commented 1 month ago

宕机可能是代码健壮性的问题,这就是为啥不敢用最新的版本,问题可能会很多,假如没那么多需求,可以自己写一下链路

Nancy7zt commented 1 month ago

写一个langchain的链路吗 还是什么

SwordHG commented 1 month ago

不用langchain,自己写一个rag链路