VSCode 설정 예시와 함께 살펴보는 Axolotl 디버깅 모범 사례

Axolotl은 LLM 파인튜닝에 유용한 훌륭한 프로젝트입니다. 이 프로젝트에 기여하기 시작하면서 디버깅이 쉽지 않다는 것을 느꼈고, 그 과정에서 익힌 팁과 노하우를 VSCode 디버깅 설정 파일과 함께 공유하고자 합니다. 무엇보다, Axolotl 디버깅 능력을 갖추면 버그를 만났을 때나 코드 동작 방식을 파악하고 싶을 때 개발자로서 더 주도적으로 대응할 수 있습니다. 이 문서가 여러분의 시작에 도움이 되길 바랍니다.
이 블로그 포스트의 내용을 Axolotl 프로젝트 문서로 직접 기여했습니다. 해당 내용은 Axolotl 저장소에서 확인할 수 있습니다.
디버깅할 때는 테스트 시나리오를 최대한 단순하게 만드는 것이 효과적입니다. 아래에 그 방법을 소개합니다.
아래의 팁은 모두 하단의 VSCode 디버깅 예시 설정에 반영되어 있습니다.
최신 버전의 Axolotl을 사용하고 있는지 확인하세요: 이 프로젝트는 자주 변경되고 버그 수정도 빠르게 이루어집니다. 현재 git 브랜치를 확인하고 main에서 최신 변경사항을 pull했는지 반드시 확인하세요.
동시성 제거: 학습과 데이터 전처리 모두 프로세스 수를 1로 제한하세요.
CUDA_VISIBLE_DEVICES를 GPU 한 개로 설정하세요. 예: export CUDA_VISIBLE_DEVICES=0.dataset_processes: 1를 지정하거나, 학습 명령 실행 시 --dataset_processes=1를 추가하세요.소규모 데이터셋 활용: 직접 만들거나 HF Hub에서 소규모 데이터셋을 사용하세요. 소규모 데이터셋을 쓸 때는 오류를 방지하기 위해 sample_packing: False와 eval_sample_packing: False를 설정해야 하는 경우가 많습니다. 시간이 없어 소규모 데이터셋을 직접 만들기 어렵고 HF Hub의 데이터를 사용해야 한다면, 데이터를 샤딩하는 방법도 있습니다(전체 데이터셋을 토크나이징하되 일부만 학습에 활용합니다). 예를 들어 데이터셋을 20개 조각으로 나누려면 Axolotl 설정에 다음을 추가하세요.
소규모 모델 활용: TinyLlama/TinyLlama-1.1B-Chat-v1.0이 좋은 예시입니다.
반복 시간 최소화: 아래 설정으로 학습 루프가 최대한 빠르게 완료되도록 하세요.
micro_batch_size: 1max_steps: 1val_set_size: 0캐시 초기화: Axolotl은 특정 단계를 캐싱하며, 기반이 되는 HuggingFace 트레이너도 마찬가지입니다. 디버깅 시 이러한 캐시를 초기화해야 할 수 있습니다.
dataset_prepared_path:에 지정된 디렉토리를 삭제하는 것이 좋습니다. 해당 값을 설정하지 않은 경우 기본값은 last_run_prepared입니다.~/.cache/huggingface/datasets/... 폴더를 삭제하여 캐시를 초기화해야 합니다.아래 예시는 sharegpt 형식의 데이터 전처리를 VSCode로 디버깅하도록 설정하는 방법을 보여줍니다. 이 형식은 Axolotl 설정에 다음과 같이 지정했을 때 사용됩니다.
VSCode 고급 디버깅에 이미 익숙하다면 아래 설명을 건너뛰고 .vscode/launch.json과 .vscode/tasks.json 파일에서 예시 설정을 바로 확인하세요.
글보다 영상이 편하다면 아래 동영상 튜토리얼로 바로 넘어가도 됩니다(둘 다 함께 보는 것을 권장합니다).
코드 변경사항이 런타임에 즉시 반영되도록 Axolotl을 편집 가능 모드(editable install)로 설치하세요. 프로젝트 루트 디렉토리에서 다음 명령을 실행합니다.
원격 호스트에서 개발하는 경우, VSCode를 활용해 원격 디버깅을 손쉽게 설정할 수 있습니다. Remote - SSH 가이드를 참고하여 설정하세요. 아래의 Docker 및 Remote SSH 디버깅 영상도 참고할 수 있습니다.
가장 빠른 시작 방법은 Axolotl GitHub 저장소의 .vscode/launch.json 파일을 수정하는 것입니다. 이는 예시 설정이므로 필요에 맞게 수정하거나 복사해서 사용하세요.
예를 들어 cd devtools && CUDA_VISIBLE_DEVICES=0 accelerate launch -m axolotl.cli.train dev_sharegpt.yml 명령을 그대로 재현하려면 아래 설정을 사용하세요1. Axolotl 설정을 오버라이드하는 추가 플래그와 위에서 소개한 팁들이 주석과 함께 포함되어 있습니다. 작업 디렉토리는 devtools로 지정하고, env 변수 HF_HOME은 임시 폴더로 설정합니다. 이는 매 실행 전 HF 데이터셋 캐시를 삭제하여 데이터 전처리 코드가 처음부터 다시 실행되도록 하기 위함입니다.
// https://github.com/OpenAccess-AI-Collective/axolotl/blob/main/.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug axolotl prompt - sharegpt",
"type": "python",
"module": "accelerate.commands.launch",
"request": "launch",
"args": [
"-m", "axolotl.cli.train", "dev_sharegpt.yml",
// The flags below simplify debugging by overriding the axolotl config
// with the debugging tips above. Modify as needed.
"--dataset_processes=1", // limits data preprocessing to one process
"--max_steps=1", // limits training to just one step
"--batch_size=1", // minimizes batch size
"--micro_batch_size=1", // minimizes batch size
"--val_set_size=0", // disables validation
"--sample_packing=False", // disables sample packing which is necessary for small datasets
"--eval_sample_packing=False",// disables sample packing on eval set
"--dataset_prepared_path=temp_debug/axolotl_outputs/data", // send data outputs to a temp folder
"--output_dir=temp_debug/axolotl_outputs/model" // send model outputs to a temp folder
],
"console": "integratedTerminal", // show output in the integrated terminal
"cwd": "${workspaceFolder}/devtools", // set working directory to devtools from the root of the project
"justMyCode": true, // step through only axolotl code
"env": {"CUDA_VISIBLE_DEVICES": "0", // Since we aren't doing distributed training, we need to limit to one GPU
"HF_HOME": "${workspaceFolder}/devtools/temp_debug/.hf-cache"}, // send HF cache to a temp folder
"preLaunchTask": "cleanup-for-dataprep", // delete temp folders (see below)
}
]
}이 설정에 대한 추가 설명:
justMyCode 인수는 true으로 설정되어 있어 Axolotl 코드만 단계별로 실행할 수 있습니다. 의존성 코드까지 들어가고 싶다면 false로 변경하세요.preLaunchTask: cleanup-for-dataprep는 .vscode/tasks.json에 정의되어 있으며, 데이터 전처리 코드가 처음부터 다시 실행되도록 디버깅 전에 아래 폴더들을 삭제합니다.
./devtools/temp_debug/axolotl_outputs./devtools/temp_debug/.hf-cache/datasets폴더 삭제가 항상 필요한 것은 아닙니다. 예를 들어 데이터 전처리가 아닌 모델 학습을 디버깅하는 경우에는 캐시나 출력 폴더를 삭제하지 않는 것이 좋습니다. 사용 사례에 따라 tasks.json 파일에 추가 태스크를 정의해야 할 수도 있습니다.
아래는 cleanup-for-dataprep 태스크를 정의하는 ./vscode/tasks.json 파일입니다. 이 태스크는 위 설정을 사용할 때 디버깅 세션마다 실행됩니다. 앞서 언급한 두 폴더를 각각 삭제하는 태스크 두 개와, 이를 하나로 묶는 복합 태스크 cleanup-for-dataprep로 구성되어 있습니다. VSCode에서 launch.json 파일의 preLaunchTask 인수에 여러 태스크를 직접 지정할 수 없기 때문에 복합 태스크가 필요합니다.
// https://github.com/OpenAccess-AI-Collective/axolotl/blob/main/.vscode/tasks.json
// this file is used by launch.json
{
"version": "2.0.0",
"tasks": [
// this task changes into the devtools directory and deletes the temp_debug/axolotl_outputs folder
{
"label": "delete-outputs",
"type": "shell",
"command": "rm -rf temp_debug/axolotl_outputs",
"options":{ "cwd": "${workspaceFolder}/devtools"},
"problemMatcher": []
},
// this task changes into the devtools directory and deletes the `temp_debug/.hf-cache/datasets` folder
{
"label": "delete-temp-hf-dataset-cache",
"type": "shell",
"command": "rm -rf temp_debug/.hf-cache/datasets",
"options":{ "cwd": "${workspaceFolder}/devtools"},
"problemMatcher": []
},
// this task combines the two tasks above
{
"label": "cleanup-for-dataprep",
"dependsOn": ["delete-outputs", "delete-temp-hf-dataset-cache"],
}
]
}실제 디버깅 상황은 위 예시와 다를 수 있습니다. 가장 간단한 방법은 devtools 폴더에 자신의 Axolotl 설정 파일을 넣고, launch.json 파일이 해당 설정을 참조하도록 수정하는 것입니다. 상황에 따라 preLaunchTask에서 삭제할 폴더를 바꾸거나, 아무것도 삭제하지 않도록 수정할 수도 있습니다.
다음 동영상 튜토리얼에서 위 설정 내용과 VSCode 디버깅 방법을 직접 확인할 수 있습니다.
Axolotl 공식 Docker 이미지를 활용하면 편리하게 디버깅할 수 있으며, Axolotl을 사용하는 가장 일반적인 방법 중 하나입니다. 다만 VSCode를 Docker에 연결하려면 몇 가지 추가 단계가 필요합니다.
Axolotl이 실행되는 호스트(예: 원격 호스트를 사용하는 경우)에서 Axolotl 저장소를 클론하고 루트 디렉토리로 이동하세요.
이미 Axolotl을 클론한 경우, 최신 변경사항을 반영한 뒤 프로젝트 루트 디렉토리로 이동하세요.
이제 원하는 Docker 이미지를 실행하고 현재 디렉토리를 마운트합니다. 아래 명령을 사용하세요.2
사용 가능한 컨테이너 목록은 README의 Docker 섹션과 DockerHub 저장소를 참고하세요. Docker 컨테이너 빌드 방식에 대한 자세한 내용은 Axolotl의 Docker CI 빌드를 확인하세요.
컨테이너에 진입한 뒤, Axolotl을 편집 가능 모드로 설치합니다.
원격 호스트를 사용하는 경우, 먼저 VSCode로 해당 호스트에 원격 접속하세요. 로컬 호스트라면 이 단계를 건너뛰어도 됩니다.
이제 VSCode 명령 팔레트(CMD + SHIFT + P)에서 Dev Containers: Attach to Running Container...를 선택합니다. 연결할 컨테이너를 선택하라는 메시지가 표시되면 방금 생성한 컨테이너를 선택하세요. 이후 프로젝트 루트를 작업 디렉토리로 하는 컨테이너 환경이 열립니다. 코드 변경사항은 컨테이너와 호스트 양쪽에 모두 반영됩니다.
이제 앞서 설명한 방식으로 디버깅을 시작할 준비가 됐습니다(VSCode로 디버깅하기 참고).
원격 호스트의 Docker 컨테이너에 연결하는 방법을 보여주는 짧은 영상입니다.