from contextlib import redirect_stdout from io import StringIO from unittest import mock import pytest from litgpt.__main__ import main def test_cli(): out = StringIO() with pytest.raises(SystemExit), redirect_stdout(out), mock.patch("sys.argv", ["litgpt", "-h"]): main() out = out.getvalue() assert "usage: litgpt" in out assert ( "{download,chat,finetune,finetune_lora,finetune_full,finetune_adapter,finetune_adapter_v2," "pretrain,generate,generate_full,generate_adapter,generate_adapter_v2,generate_sequentially," "generate_speculatively,generate_tp,convert_to_litgpt,convert_from_litgpt,convert_pretrained_checkpoint," "merge_lora,evaluate,serve,validate}" in out ) assert ( """Available subcommands: download Download weights or tokenizer data from the Hugging Face Hub. chat Chat with a model.""" in out ) assert """evaluate Evaluate a model with the LM Evaluation Harness.""" in out assert """serve Serve a LitGPT model using LitServe.""" in out out = StringIO() with pytest.raises(SystemExit), redirect_stdout(out), mock.patch("sys.argv", ["litgpt", "finetune_lora", "-h"]): main() out = out.getvalue() assert ( """--lora_alpha LORA_ALPHA The LoRA alpha. (type: int, default: 16)""" in out ) out = StringIO() with pytest.raises(SystemExit), redirect_stdout(out), mock.patch("sys.argv", ["litgpt", "pretrain", "-h"]): main() out = out.getvalue() print(out) assert ( """--train.max_tokens MAX_TOKENS Total number of tokens to train on (type: int | None, default: 3000000000000)""" in out ) def test_pretrain_allows_max_steps(): # Ensure --train.max_steps is accepted by the CLI for pretrain # and only emits a warning instead of raising a validation error. args = [ "litgpt", "pretrain", "pythia-14m", "--train.max_steps=1", "--out_dir=out/test-cli", ] with pytest.warns(UserWarning, match="max_steps"): try: with mock.patch("sys.argv", args): main() except Exception: pass def test_rewrite_finetune_command(): out1 = StringIO() with pytest.raises(SystemExit), redirect_stdout(out1), mock.patch("sys.argv", ["litgpt", "fineune", "-h"]): main() out2 = StringIO() with pytest.raises(SystemExit), redirect_stdout(out2), mock.patch("sys.argv", ["litgpt", "fineune_lora", "-h"]): main() assert out1.getvalue() == out2.getvalue()