Repository: mosaicml/composer

Issue:
TQDM spams lines during validation when running trainer.fit() in notebook
** Environment **
Colab notebook.

<img width="607" alt="TQDM Spam" src="https://user-images.githubusercontent.com/11728034/151625792-31dc2c0e-d572-43d1-9514-5127a6a3751b.png">

** To reproduce

run `trainer.fit()` in a Colab notebook. See [this notebook](https://colab.research.google.com/drive/12Dl0NVDaj4tf4gfpfg-rkIAoO_H7edo3?usp=sharing) for an example.

## Expected behavior

TQDM output should remain on a single line during evaluation, which happens during training.



Discussion:
I think the solution here is for `composer` to import from `tqdm.notebook import tqdm` based on a trainer arg
I think TQDM can actually autodetect whether to run in a notebook or shell environment if we use `from tqdm.autonotebook import tqdm`

Resolving patch:
diff --git a/composer/loggers/tqdm_logger.py b/composer/loggers/tqdm_logger.py
--- a/composer/loggers/tqdm_logger.py
+++ b/composer/loggers/tqdm_logger.py
@@ -6,8 +6,8 @@
 from dataclasses import asdict, dataclass
 from typing import TYPE_CHECKING, Any, Dict, List, Optional
 
-import tqdm
 import yaml
+from tqdm import auto
 
 from composer.core.logging import LogLevel, TLogData, TLogDataValue, format_log_data_value
 from composer.core.logging.base_backend import BaseLoggerBackend
@@ -35,7 +35,7 @@ class _TQDMLoggerInstance:
 
     def __init__(self, state: _TQDMLoggerInstanceState) -> None:
         self.state = state
-        self.pbar = tqdm.tqdm(total=state.total,
+        self.pbar = auto.tqdm(total=state.total,
                               desc=state.description,
                               position=state.position,
                               bar_format="{l_bar}{bar:10}{r_bar}{bar:-10b}")
@@ -65,12 +65,12 @@ class TQDMLoggerBackend(BaseLoggerBackend):
 
     Example output::
 
-        Epoch 1: 100%|██████████| 64/64 [00:01<00:00, 53.17it/s, loss/train=2.3023]                                                                                 
-        Epoch 1 (val): 100%|██████████| 20/20 [00:00<00:00, 100.96it/s, accuracy/val=0.0995]  
+        Epoch 1: 100%|██████████| 64/64 [00:01<00:00, 53.17it/s, loss/train=2.3023]
+        Epoch 1 (val): 100%|██████████| 20/20 [00:00<00:00, 100.96it/s, accuracy/val=0.0995]
 
     .. note::
 
-        It is currently not possible to show additional metrics. 
+        It is currently not possible to show additional metrics.
         Custom metrics for the TQDM progress bar will be supported in a future version.
 
     Args:


Test patch:
diff --git a/tests/test_logger.py b/tests/test_logger.py
--- a/tests/test_logger.py
+++ b/tests/test_logger.py
@@ -5,8 +5,8 @@
 from unittest.mock import MagicMock
 
 import pytest
-import tqdm
 from _pytest.monkeypatch import MonkeyPatch
+from tqdm import auto
 
 from composer.core.event import Event
 from composer.core.logging import Logger, LogLevel
@@ -82,7 +82,8 @@ def get_mock_tqdm(position: int, *args, **kwargs):
         is_train_to_mock_tqdms[is_train].append(mock_tqdm)
         return mock_tqdm
 
-    monkeypatch.setattr(tqdm, "tqdm", get_mock_tqdm)
+    monkeypatch.setattr(auto, "tqdm", get_mock_tqdm)
+
     max_epochs = 2
     mosaic_trainer_hparams.max_duration = f"{max_epochs}ep"
     mosaic_trainer_hparams.loggers = [TQDMLoggerBackendHparams()]