인공지능 공부 진척도: 78%|████████████████▍ | 78/100 [00:38<00:10, 2.02it/s]
모델 학습을 진행하면서, 위와 같은 진행 바(Progress Bar)를 정말 많이 보셨을 겁니다.
(저도 인공지능 공부를 처음 시작해서, 책에 있는 코드를 막 따라쳤을 때, 저 진행 바를 보고 '우와!' 하고 설렜던 기억이 아직도 새록새록하네요.)
위 진행 바는, Python의 'tqdm' 모듈을 이용한 것입니다!
tqdm은 Python으로 어떤 작업을 할 때 프로그램이 내가 의도한 대로 돌아가고 있는 중인지, 얼마나 진행되었는지를 확인하기 위해서 사용합니다.
많은 시간이 걸리는 작업의 경우에, 얼마나 시간이 남았는지, 진행도를 확인하는 것이 특히 중요한데요, 따라서 많은 경우에 모델 학습 시 tqdm을 활용하는 모습을 볼 수 있습니다.
tqdm은 주로 세 가지 사용 방법으로 나눠볼 수 있습니다.
우선, list, dict나 range와 같은 iterable 객체를 이용하는 방법이 있고, 이 방법으로 한번 이해해보도록 합시다.
from tqdm import tqdm # pip install tqdm
import time
iterable = ['A', 'I', 'D', 'i', 's', 'B', 'E', 'S', 'T']
bar = tqdm(iterable, # 진행 상황을 표시할 iterable 객체.
desc = 'Description', # 진행 상황 표시줄의 제목.
total = len(iterable), # 전체 반복량 (확률에서의 분모).
leave = True, # 잔상 남김 여부, 기본적으로 True
ncols = 100, # 진행 바 길이. px 단위
ascii = ' =', # 바 모양, 첫 번째 문자는 공백이어야 함
initial = 0 # 진행 시작값
)
for c in bar:
time.sleep(0.1)
Output :
Description: 100%|====================================================| 9/9 [00:00<00:00, 9.88it/s]
tqdm()
으로 iterable 객체를 감싸고, 위에서 설명된 method를 적절하게 사용하는 방법으로, 내 마음에 쏙 드는 Progress Bar를 만들 수 있습니다.
for c in bar:
bar.set_description(f"Description '{c}'")
time.sleep(0.1)
Output :
Description 'T': 100%|================================================| 9/9 [00:00<00:00, 9.87it/s]
또한, 위와 같은 방식으로 루프를 돌면서도, bar의 description을 바꿀 수도 있죠.
for i in trange(100):
time.sleep(0.01)
Output :
100%|██████████| 100/100 [00:01<00:00, 91.13it/s]
trange(i)라는 특별한 인스턴스도 존재하는데, 이는 tqdm(range(i))
와 같은 의미를 가지고 있습니다.
with tqdm(total=100) as bar:
for i in range(10):
time.sleep(0.1)
bar.update(10)
with 구문과, update()를 통해서 bar를 수동으로 컨트롤할 수 있습니다. iterable한 객체를 토대로 tqdm을 갱신시키는 것이 아니라, 수동으로 퍼센트를 올린다고 보면 좋을 것 같습니다.
또한, tqdm은 스크립트나 커맨드라인에서도 매우 유용하게 사용될 수 있습니다. 파이프 사이에 tqdm을 삽입하기만 하면, 모든 stdin을 stdout으로 전달하면서 stderr에 진행 상황을 출력합니다.
$ time find . -name '*.py' -type f -exec cat {} \; | wc -l
Output :
857365
real 0m3.458s
user 0m0.274s
sys 0m3.325s
sh에서 위 명령어를 입력하면, 아래와 같은 과정을 거쳐 그 결과를 얻을 수 있습니다.
1) `find .` : 현재 디렉토리(.)와 그 하위 디렉토리를 탐색하고
2) `-name '*.py': .py 확장자를 가진 파일을 찾고`
3) `-type f` : 파일 타입이 '파일(f)'인 항목만 찾는다.
4) `-exec cat {} \;` : 이 때, 찾은 각 파일({}는 각 파일 경로)에 대해 cat 명령을 실행한다. (cat은 파일의 내용을 표준 출력(stdout)으로 보냄) \;는 -exec 옵션의 끝을 나타낸다.
5) `|` : 파이프(pipe)는 한 명령의 출력을 다른 명령의 입력으로 전달한다. 여기서는 find 명령의 출력(즉, Python 파일의 내용)을 wc -l 명령의 입력으로 전달한다.
6) `wc -l` : wc는 'Word Count'의 약자로, 텍스트 데이터의 라인 수, 단어 수 등을 계산하는 명령이다. 이 때, -l 옵션을 사용하였으므로 라인 수(line count)만을 출력하도록 한다.
이 때, 이러한 명령 pipe 사이에서 tqdm을 이용해서 현재 진행도를 확인할 수 있습니다.
$ time find . -name '*.py' -type f -exec cat \{} \; | tqdm | wc -l
Output :
857366it [00:03, 246471.31it/s]
857365
real 0m3.585s
user 0m0.862s
sys 0m3.358s
커맨드라인에서도 진행상황을 시각적으로 쉽게 확인할 수 있다니, 굉장히 신기하지 않나요?
진행 상황을 쉽게 확인할 수 있는 tqdm!
더 자세한 내용은 아래 링크의 tqdm documentation을 참고해보세요 🙂
작성자 : 2기 안준영