推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
gosky
V2EX  ›  Python

Python asyncio 中怎么执行 cpu 密集型任务?

  •  
  •   gosky · Jul 23, 2024 · 7972 views
    This topic created in 832 days ago, the information mentioned may be changed or developed.
    理论上讲,两个办法:
    一、多线程,但不知道怎么全局解释锁被优化得怎么样
    二、多进程,消耗更多内存,因为需要加载模型,内存复制必须要考虑。多进程管理是个麻烦,启动耗时也得考虑

    期望有个轻量级的开源程序,轻松完成这个活……
    Supplement 1  ·  Jul 23, 2024
    其中的 cpu 密集型,依赖 python 库
    Supplement 2  ·  Jul 24, 2024
    问了下 ai ,pytorch c 扩展大部分会释放 gil ,于是决定采用多线程的方式
    但……实际运行后,发现虽然自己撸灵活,还是专用推理服务更节省资源
    25 replies  •  2024-08-02 10:49:58 +08:00
    changz
    changz
    Jul 23, 2024 via Android
    1
    多线程+c/c++ ffi
    gaogang
    gaogang
    Jul 23, 2024
    2
    cpu 密集的任务 用其他合适的语言实现
    然后通过 rpc 暴露出来 正好给 python 的 asyncio 调
    tf2
    tf2
    Jul 23, 2024❤️1
    3
    asyncio 顾名思义是 异步 io 。。。众所周知,py 要么卡 cpu 要么卡 io ,asyncio 只解决卡 io 的问题啊。
    ysn2233
    ysn2233
    Jul 23, 2024❤️1
    5
    用 c/c++/rust 的 ffi 做 binding 吧,实在不行 java/go 什么的也行,python 就做个前端调一下
    mirrornighth
    mirrornighth
    Jul 23, 2024
    6
    多进程
    ipwx
    ipwx
    Jul 23, 2024
    7
    “因为需要加载模型,内存复制必须要考虑。”

    你是啥模型。有些模型开多线程是可以并行的。
    Sezxy
    Sezxy
    Jul 23, 2024
    8
    python 3.13 可以加个参数去掉 GIL
    guochao
    guochao
    Jul 23, 2024
    9
    针对锁和 python 效率的问题:
    - 如果你的计算任务可以用 c/rust 的模块,最好是在 c/rust 的部分处理,最好能批处理
    - 如果是 pure python ,也许可以试试 taichi 或者类似的东西。因为 python 可以被再次编译成 native 或者 gpu kernel ,并针对架构优化
    针对 asyncio 只管异步切换,计算存在长时间阻塞的问题
    - (不同进程、单独服务的方案)要么 celery ,或者自己搓一个简单的队列
    - (简单在同一个进程中的方案)要么 thread pool executor
    simple2025
    simple2025
    Jul 23, 2024
    11
    你加载的模型很大吗?不然想不出来为什么不用多进程
    ruanimal
    ruanimal
    Jul 23, 2024
    12
    跑模型还是多进程好
    razertory
    razertory
    Jul 23, 2024
    13
    asyncio 是做 IO 密集任务的,不是做 CPU 密集任务
    scipelaina
    scipelaina
    Jul 23, 2024
    14
    `asyncio.to_thread`; `concurrent.futures`.
    日经问题,Mark as Duplicated.
    wujian752
    wujian752
    Jul 23, 2024 via iPhone
    15
    如果是神经网络模型现在 onnxruntime 在 inference 的时候可以不受 GIL 影响
    crackidz
    crackidz
    Jul 23, 2024
    16
    Python 主要冷启动耗时几十 ms 左右,剩下的交到你的代码中了,启动时间主要取决于你的代码吧...

    上面说的基本差不多了,但现在不推荐用那个 nogil 版本,要改你的代码支持部分功能,第三方库也未见得支持。另外还有一些隐蔽 bug...
    yoiteshaw
    yoiteshaw
    Jul 23, 2024❤️1
    17
    我工作中遇到过类似的事情,两年前,无论怎么优化都收效甚微,多线程因为 GIL 反而更慢,最后不得已用多进程去做,用 socket 去通信。
    今年我推翻用 rust 重写了,一些逻辑直接的遍历,简简单单 pair_iter 解决,心情舒畅。
    sagaxu
    sagaxu
    Jul 23, 2024
    18
    Python 的 CPU 密集型库大都用 C 实现,大部分时间不会持有 GIL
    skuuhui
    skuuhui
    Jul 24, 2024
    19
    最简单是写个 c++模块,用 python 去调。
    其他方法有
    1. 换个没锁的解释器
    2. wasm
    3. https://numba.pydata.org/ ,https://www.trypyjion.com/
    Nich0la5
    Nich0la5
    Jul 24, 2024
    20
    asyncio 就不是给你做 cpu 密集型用的
    gray0
    gray0
    Jul 24, 2024
    21
    何必多 BB 直接上代码

    from concurrent.futures import ProcessPoolExecutor
    import asyncio

    async def integration_process_and_gather():
    with ProcessPoolExecutor() as process_pool:
    loop = asyncio.get_running_loop()
    numbers = [100000000, 1, 100, 10000, 1000000, 1000, 100000]
    tasks = [
    loop.run_in_executor(process_pool, do_count_number, n) for n in numbers
    ]
    [print(type(task)) for task in tasks]
    results = await asyncio.gather(*tasks)
    print(f"integration_hello_world {results}")
    yh7gdiaYW
    yh7gdiaYW
    Jul 24, 2024
    22
    简单点就多进程,复杂点就上 ray ,可以分布式计算用得很爽
    lttzzlll
    lttzzlll
    Jul 25, 2024
    23
    你提出的问题,限制你的思路。web 服务要简单,轻量,快速响应。推理服务耗时耗资源。正确的方式应该是 同一个项目(git repo),部署多个进程。经典的做法应该是 一个 web 服务进程,多个 worker 进程,web 服务和 worker 进程之间用队列。以 django/flask 举例:
    lttzzlll
    lttzzlll
    Jul 25, 2024
    24
    @lttzzlll 。。。你面的问题不是“Python asyncio 中怎么执行 cpu 密集型任务?”。 换成其他的 web 框架或语言,就没有这种问题了吗?而是在 web 服务中,如何处理比较耗时/耗资源的任务。这些问题都有很经典很成熟的方案。把这类任务放到 worker 节点上,用队列传递消息,不够就增加 replica 的数量。非常成熟和广泛使用的方案,你的场景也不例外。
    cooljiang
    cooljiang
    Aug 2, 2024
    25
    CPU 密集型任务建议换个没 GIL 的 Python 解释器,如 PyPy 之类的。
    关于 GIL: https://mp.weixin.qq.com/s/lIkcTuCX5htQcteklCFaZw
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1271 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 55ms · UTC 21:10 · PVG 05:10 · LAX 13:10 · JFK 16:10
    ♥ Do have faith in what you're doing.