多处理+记录+ TQDM进度栏闪烁
tqdm
有经验的人可以帮助我使用以下复制器吗?
import itertools
import logging
import multiprocessing
import random
import sys
import time
import tqdm
from tqdm.contrib import DummyTqdmFile
log: logging.Logger = logging.getLogger(__name__)
DEFAULT_FORMAT = "[%(asctime)s.%(msecs)06d][%(processName)s][%(threadName)s][%(levelname)s][%(module)s] %(message)s"
VERBOSITY = 1
def configure_logger(log: logging.Logger, verbosity: int, *, format: str = DEFAULT_FORMAT, dry_run: bool = False):
"""Configures the logger instance based on verbosity level"""
# can't use force=true as it requires Python >= 3.8
root = logging.getLogger()
for handler in root.handlers:
root.removeHandler(handler)
if dry_run:
format = format.replace(" %(message)s", "[DRY RUN] %(message)s")
logging.basicConfig(format=format, datefmt="%Y-%m-%d %H:%M:%S", stream=DummyTqdmFile(sys.stdout))
verbosity_to_loglevel = {0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG}
log.setLevel(verbosity_to_loglevel[min(verbosity, 2)])
if verbosity >= 4:
logging.getLogger().setLevel(logging.INFO)
if verbosity >= 5:
logging.getLogger().setLevel(logging.DEBUG)
def by_n(iterable, n):
"""Iterate by chunks of n items"""
return (tuple(filter(lambda x: x is not None, x)) for x in itertools.zip_longest(*[iter(iterable)] * n))
def _worker(batch):
log.info("Let's go!")
for i in batch:
log.info("Processing item %d", i)
time.sleep(random.uniform(0.1, 0.2))
log.info("Done!")
return len(batch)
if __name__ == "__main__":
configure_logger(log, VERBOSITY)
log.info("Let's go!")
foos = list(range(1000))
kwargs = {
"desc": "Processing...",
"total": len(foos),
"leave": True,
"mininterval": 1,
"maxinterval": 5,
"unit": "foo",
"dynamic_ncols": True,
}
pbar = tqdm.tqdm(**kwargs)
with multiprocessing.Pool(processes=5) as workers_pool:
for batch_length in workers_pool.imap_unordered(
_worker,
by_n(foos, min(10 + int((len(foos) - 10) / 100), 1000)),
):
pbar.update(batch_length)
log.info("Done!")
当我设置verbosity = 0
时,log
来自工作过程中的调用均未输出,并且进度栏将正确显示。
但是,一旦我通过设置andbosity = 1
来登录工作过程,那么这是
- 在正确定位进度栏并粘在屏幕底部的情况下,
- 大多数时候都会显示进度
0%
,偶尔它以适当的进度和百分比闪烁
Can someone experienced with tqdm
help me with the following reproducer please?
import itertools
import logging
import multiprocessing
import random
import sys
import time
import tqdm
from tqdm.contrib import DummyTqdmFile
log: logging.Logger = logging.getLogger(__name__)
DEFAULT_FORMAT = "[%(asctime)s.%(msecs)06d][%(processName)s][%(threadName)s][%(levelname)s][%(module)s] %(message)s"
VERBOSITY = 1
def configure_logger(log: logging.Logger, verbosity: int, *, format: str = DEFAULT_FORMAT, dry_run: bool = False):
"""Configures the logger instance based on verbosity level"""
# can't use force=true as it requires Python >= 3.8
root = logging.getLogger()
for handler in root.handlers:
root.removeHandler(handler)
if dry_run:
format = format.replace(" %(message)s", "[DRY RUN] %(message)s")
logging.basicConfig(format=format, datefmt="%Y-%m-%d %H:%M:%S", stream=DummyTqdmFile(sys.stdout))
verbosity_to_loglevel = {0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG}
log.setLevel(verbosity_to_loglevel[min(verbosity, 2)])
if verbosity >= 4:
logging.getLogger().setLevel(logging.INFO)
if verbosity >= 5:
logging.getLogger().setLevel(logging.DEBUG)
def by_n(iterable, n):
"""Iterate by chunks of n items"""
return (tuple(filter(lambda x: x is not None, x)) for x in itertools.zip_longest(*[iter(iterable)] * n))
def _worker(batch):
log.info("Let's go!")
for i in batch:
log.info("Processing item %d", i)
time.sleep(random.uniform(0.1, 0.2))
log.info("Done!")
return len(batch)
if __name__ == "__main__":
configure_logger(log, VERBOSITY)
log.info("Let's go!")
foos = list(range(1000))
kwargs = {
"desc": "Processing...",
"total": len(foos),
"leave": True,
"mininterval": 1,
"maxinterval": 5,
"unit": "foo",
"dynamic_ncols": True,
}
pbar = tqdm.tqdm(**kwargs)
with multiprocessing.Pool(processes=5) as workers_pool:
for batch_length in workers_pool.imap_unordered(
_worker,
by_n(foos, min(10 + int((len(foos) - 10) / 100), 1000)),
):
pbar.update(batch_length)
log.info("Done!")
When I set VERBOSITY = 0
, the log
calls from the worker processes output nothing and the progress bar is displayed correctly.
However, as soon as I log from the worker processes by setting VERBOSITY = 1
, then here's what happening
- While the progress bar is properly positioned and sticks to the bottom of the screen
- Most of the time displays a progress of
0%
and only occasionally it flashes with the proper progress and percentage
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也许这将部分有所帮助。这涉及多处理的进展。
进行了一些研究之后,我写了一个名为 parallelalbar 的小模块。它允许您分别显示池的整体进度和每个核心的整体进度。
它易于使用并且具有很好的描述。
例如:
Maybe this will partially help. This concerns progress in multiprocessing.
After doing some research, I wrote a small module called parallelbar. It allows you to display both the overall progress of the pool and for each core separately.
It is easy to use and has a good description.
For example: