মাল্টিপ্রসেসিং: প্রগতি বারটি প্রদর্শন করতে tqdm ব্যবহার করুন


103

আমার কোডটিকে আরও "পাইথোনিক" এবং দ্রুততর করার জন্য, আমি "মাল্টিপ্রসেসিং" এবং একটি মানচিত্র ফাংশন এটি প্রেরণের জন্য ব্যবহার করি) ক) ফাংশন এবং খ) পুনরাবৃত্তির পরিসর।

ইমপ্লান্টেড সলিউশন (অর্থাত্ tqdm কল করুন tqdm.tqdm রেঞ্জের উপর সরাসরি (পরিসীমা (0, 30%)) মাল্টিপ্রসেসিং (নীচের কোড অনুসারে) দ্বারা কাজ করে না।

অগ্রগতি বারটি 0 থেকে 100% পর্যন্ত প্রদর্শিত হয় (যখন পাইথন কোডটি পড়ে?) তবে এটি মানচিত্রের কার্যকারিতাটির প্রকৃত অগ্রগতি নির্দেশ করে না।

অগ্রগতি বারটি কীভাবে প্রদর্শিত হবে যা নির্দেশ করে যে 'ম্যাপ' ফাংশনটি কোন ধাপে রয়েছে?

from multiprocessing import Pool
import tqdm
import time

def _foo(my_number):
   square = my_number * my_number
   time.sleep(1)
   return square 

if __name__ == '__main__':
   p = Pool(2)
   r = p.map(_foo, tqdm.tqdm(range(0, 30)))
   p.close()
   p.join()

কোন সহায়তা বা পরামর্শ স্বাগত ...


আপনি কি অগ্রগতি বারের স্নিপেট পোস্ট করতে পারেন?
অ্যালেক্স

4
সঙ্গে একটি সমাধান জন্য অনুসন্ধান মানুষের জন্য .starmap(): এখানে একটি প্যাচ হয় Poolযোগ .istarmap(), যা সঙ্গে কাজ করবে tqdm
ডারকোনৌট

উত্তর:


136

মানচিত্রের পরিবর্তে ইম্যাপ ব্যবহার করুন, যা প্রক্রিয়াজাত মানগুলির পুনরাবৃত্তি প্রদান করে।

from multiprocessing import Pool
import tqdm
import time

def _foo(my_number):
   square = my_number * my_number
   time.sleep(1)
   return square 

if __name__ == '__main__':
   with Pool(2) as p:
      r = list(tqdm.tqdm(p.imap(_foo, range(30)), total=30))

14
একটি বদ্ধ তালিকা () বিবৃতি পুনরাবৃত্তির শেষ হওয়ার জন্য অপেক্ষা করে। মোট = এছাড়াও যেহেতু tqdm কতকাল পুনরাবৃত্তির হতে হবে জানে না প্রয়োজন হয়,
hkyi

16
এর জন্য কি একই রকম সমাধান আছে starmap()?
তারাশিপকা

4
for i in tqdm.tqdm(...): pass আরও সোজা-ফরোয়ার্ড হতে পারে, সেটিlist(tqdm.tqdm)
সার্ভড

4
এটি কাজ করে তবে কি অন্য কারও কাছে এটি প্রতিটি পুনরুক্তির জন্য একটি নতুন লাইনে ক্রমাগত অগ্রগতি বারটি মুদ্রণ করেছিল?
ডেনিস সুবাচেভ

4
আচরণ নির্দিষ্ট যখন নির্দিষ্ট করা chunk_sizeহয় p.imaptqdmপ্রতিটি খণ্ডের পরিবর্তে প্রতিটি পুনরাবৃত্তি আপডেট করতে পারে ?
হুয়াংবিউইউ

56

সমাধান পাওয়া গেছে: সাবধান! মাল্টিপ্রসেসিংয়ের কারণে, অনুমানের সময় (লুপ প্রতি পুনরাবৃত্তি, মোট সময়, ইত্যাদি) অস্থির হতে পারে, তবে অগ্রগতি বারটি পুরোপুরি কার্যকর হয়।

দ্রষ্টব্য: পুলের প্রসঙ্গে পরিচালক কেবল পাইথন সংস্করণ 3.3 থেকে উপলব্ধ

from multiprocessing import Pool
import time
from tqdm import *

def _foo(my_number):
   square = my_number * my_number
   time.sleep(1)
   return square 

if __name__ == '__main__':
    with Pool(processes=2) as p:
        max_ = 30
        with tqdm(total=max_) as pbar:
            for i, _ in enumerate(p.imap_unordered(_foo, range(0, max_))):
                pbar.update()

4
pbar.close()প্রয়োজন নেই, এটি সমাপ্ত হওয়ার পরে স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবেwith
সাগর কর

4
দ্বিতীয় / অভ্যন্তরীণ tqdmকল এখানে প্রয়োজনীয়?
ছায়াছবির

7
প্রশ্নে "আর" হিসাবে ফিরিয়ে দেওয়া _ফু (আমার_নম্বার) এর আউটপুট সম্পর্কে কী?
লিকাক

4
এর জন্য কি একই রকম সমাধান আছে starmap()?
তারাশিপকা

4
@ শ্যাডোওয়ালটাকার - এটি ছাড়া কাজ করা বলে মনে হচ্ছে;)। যাইহোক - imap_unorderedএখানে কী, এটি সেরা পারফরম্যান্স এবং সেরা অগ্রগতির বার অনুমান দেয়।
টমাসজ গ্যান্ডোর

23

দেরী হওয়ার জন্য দুঃখিত তবে আপনার যদি যা দরকার তা যদি একটি সাময়িক মানচিত্র হয় তবে আমি এই কার্যকারিতাটি এতে যুক্ত করেছিলাম tqdm>=4.42.0:

from tqdm.contrib.concurrent import process_map  # or thread_map
import time

def _foo(my_number):
   square = my_number * my_number
   time.sleep(1)
   return square 

if __name__ == '__main__':
   r = process_map(_foo, range(0, 30), max_workers=2)

তথ্যসূত্র: https://tqdm.github.io/docs/contrib.concurrent/ এবং https://github.com/tqdm/tqdm/blob/master/example/parallel_bars.py


4
এর জন্য ধন্যবাদ. আমি চেষ্টা করেছি এমন অন্য যে কোনও সমাধানের চেয়ে খুব সহজে কাজ করে।
ব্যবহারকারী 3340499

Cool (+1 টি), কিন্তু ছোঁড়ার HBox(children=(FloatProgress(value=0.0, max=30.0), HTML(value='')))Jupyter মধ্যে
Ébe ইসহাক


আমি tqdm_notebook হ্যাক করার জন্য আলোচনার সাথে একটি সমস্যা দেখতে পাচ্ছি, তবে, tqdm.contrib.concurrent জন্য সমাধান করার কোনও সমাধান ওয়ার্কআউট করতে পারছি না।
আইজাক

এটা চমৎকার. কেবল বাক্সের বাইরে কাজ করে।
লার্স লারসন

21

p_tqdmপরিবর্তে আপনি ব্যবহার করতে পারেন ।

https://github.com/swansonk14/p_tqdm

from p_tqdm import p_map
import time

def _foo(my_number):
   square = my_number * my_number
   time.sleep(1)
   return square 

if __name__ == '__main__':
   r = p_map(_foo, list(range(0, 30)))

4
এটি অত্যন্ত ভাল কাজ করে, এবং এটি খুব সহজ ছিল pip install। এটি আমার বেশিরভাগ প্রয়োজনের জন্য টিকিডিএম প্রতিস্থাপন করছে
ক্রিপডিক

মেরকি ভিক্টর;)
গ্যাব্রিয়েল রোমন

p_tqdmসীমাবদ্ধ multiprocessing.Pool, থ্রেডের জন্য উপলভ্য নয়
পাঠাতেও

8

জাভি মার্টিনেজের উত্তরের ভিত্তিতে আমি ফাংশনটি লিখেছি imap_unordered_barimap_unorderedকোনও প্রসেসিং বার দেখানো মাত্র পার্থক্য সহ এটি একইভাবে ব্যবহার করা যেতে পারে ।

from multiprocessing import Pool
import time
from tqdm import *

def imap_unordered_bar(func, args, n_processes = 2):
    p = Pool(n_processes)
    res_list = []
    with tqdm(total = len(args)) as pbar:
        for i, res in tqdm(enumerate(p.imap_unordered(func, args))):
            pbar.update()
            res_list.append(res)
    pbar.close()
    p.close()
    p.join()
    return res_list

def _foo(my_number):
    square = my_number * my_number
    time.sleep(1)
    return square 

if __name__ == '__main__':
    result = imap_unordered_bar(_foo, range(5))

4
এটি একটি নতুন লাইনের প্রতিটি ধাপে বারটি পুনরায় আঁকবে। একই লাইনে কীভাবে আপডেট করবেন?
misantroop

আমার ক্ষেত্রে সমাধান (উইন্ডোজ / পাওয়ারশেল): কলোরামা।
মিসানট্রুপ

'পিবিআর.ক্লোজ () প্রয়োজন নেই, এটি সমাপ্ত হওয়ার পরে স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যাবে' সাগর সাজিদের @ স্কিপির জবাব সম্পর্কে মন্তব্য করেছেন
তেজস শেঠি

1

আপনার সমান্তরাল এক্সিকিউটিভ ফাংশনগুলি থেকে আপনাকে যখন ফলাফলগুলি পুনরুদ্ধার করতে হবে তখন আমার গ্রহণের বিষয়টি এখানে। এই ফাংশনটি কয়েকটি কাজ করে (আমার আরও একটি পোস্ট রয়েছে যা এটি আরও ব্যাখ্যা করে) তবে মূল বক্তব্যটি এখানে একটি কার্যবিবরণী সারি রয়েছে এবং একটি কার্য সমাপ্ত সারিতে রয়েছে। শ্রমিকরা প্রতিটি কাজটি মুলতুবি কাতারে সম্পন্ন হওয়ার সাথে সাথে তারা কাজগুলি সম্পন্ন সারিতে ফলাফল যুক্ত করে। আপনি tqdm অগ্রগতি বারের সাহায্যে সম্পন্ন সারিতে কাজটি চেকটি মোড়ানো করতে পারেন। আমি এখানে do_work () ফাংশনটি বাস্তবায়ন করছি না, এটি প্রাসঙ্গিক নয়, কারণ এখানে বার্তাটি হ'ল কাজগুলি সারি করা নিরীক্ষণ করা এবং ফলাফল যতবার আসে ততবার অগ্রগতি বার আপডেট করা।

def par_proc(job_list, num_cpus=None, verbose=False):

# Get the number of cores
if not num_cpus:
    num_cpus = psutil.cpu_count(logical=False)

print('* Parallel processing')
print('* Running on {} cores'.format(num_cpus))

# Set-up the queues for sending and receiving data to/from the workers
tasks_pending = mp.Queue()
tasks_completed = mp.Queue()

# Gather processes and results here
processes = []
results = []

# Count tasks
num_tasks = 0

# Add the tasks to the queue
for job in job_list:
    for task in job['tasks']:
        expanded_job = {}
        num_tasks = num_tasks + 1
        expanded_job.update({'func': pickle.dumps(job['func'])})
        expanded_job.update({'task': task})
        tasks_pending.put(expanded_job)

# Set the number of workers here
num_workers = min(num_cpus, num_tasks)

# We need as many sentinels as there are worker processes so that ALL processes exit when there is no more
# work left to be done.
for c in range(num_workers):
    tasks_pending.put(SENTINEL)

print('* Number of tasks: {}'.format(num_tasks))

# Set-up and start the workers
for c in range(num_workers):
    p = mp.Process(target=do_work, args=(tasks_pending, tasks_completed, verbose))
    p.name = 'worker' + str(c)
    processes.append(p)
    p.start()

# Gather the results
completed_tasks_counter = 0

with tqdm(total=num_tasks) as bar:
    while completed_tasks_counter < num_tasks:
        results.append(tasks_completed.get())
        completed_tasks_counter = completed_tasks_counter + 1
        bar.update(completed_tasks_counter)

for p in processes:
    p.join()

return results

0
import multiprocessing as mp
import tqdm


some_iterable = ...

def some_func():
    # your logic
    ...


if __name__ == '__main__':
    with mp.Pool(mp.cpu_count()-2) as p:
        list(tqdm.tqdm(p.imap(some_func, iterable), total=len(iterable)))

-2

এই পদ্ধতির সহজ এবং এটি কাজ করে।

from multiprocessing.pool import ThreadPool
import time
from tqdm import tqdm

def job():
    time.sleep(1)
    pbar.update()

pool = ThreadPool(5)
with tqdm(total=100) as pbar:
    for i in range(100):
        pool.apply_async(job)
    pool.close()
    pool.join()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.