tidyvocie2026
화자 검증 파이프라인 최적화
화자 검증 challenge에서 학습, 추론, 제출까지 이어지는 전체 파이프라인을 정리하고, 실험 반복 비용을 줄이는 쪽을 맡았다. 기존 pretrained backbone을 fine-tuning해 trial pair score를 계산하는 구조였고, 내가 주로 손댄 부분은 DataLoader 병목, 전처리 병렬화, scoring 및 제출 자동화였다.
작업한 구간
원본 코드베이스를 그대로 쓰기보다, 실제로 시간이 오래 걸리는 구간과 제출에서 터질 수 있는 구간을 먼저 봤다.
- 학습: DataLoader 구성, fbank 추출 병목, checkpoint / resume
- 추론: cohort 생성, S-Norm scoring
- 제출: 포맷 검증, row 수 검증, zip 패키징 자동화
모델 구조를 새로 짠 프로젝트라기보다, 기존 파이프라인을 실제로 더 빨리, 덜 깨지게 돌리기 위한 작업에 가까웠다.
병목 1: Data loading
원본 코드에서는 DataLoader worker 수가 2로 고정되어 있었고, 기본 설정만 사용하고 있었다. 이 상태에서는 CPU에서 데이터를 준비해 GPU로 넘기는 속도가 느렸고, 학습이 입력 공급을 기다리는 구간이 생겼다.
여기서는 아래처럼 바꿨다.
NUM_WORKERS = min(24, os.cpu_count())로 동적 조정pin_memory=Truepersistent_workers=True
worker 수를 CPU 자원에 맞게 늘리고, pinned memory로 GPU 전송 대기를 줄이고, epoch마다 worker를 다시 띄우는 오버헤드도 줄였다.
병목 2: fbank 추출
원본 코드는 forward 내부에서 배치의 각 샘플에 대해 fbank를 순서대로 계산하고 있었다. 배치 크기가 32면, 32개를 직렬로 처리하는 구조였다.
이 부분은 함수로 분리한 뒤 ThreadPoolExecutor(max_workers=8)로 병렬화했다. fbank 추출은 CPU 연산이라 GPU 쪽과 겹쳐 돌릴 수 있었고, 이 변화가 실제 시간 단축에 직접적으로 연결됐다.
최적화 효과
가장 분명했던 변화는 학습 시간이었다.
- 기존: epoch당 약 25분
- 변경 후: epoch당 15분대
수치 자체가 아주 정밀한 benchmark는 아니더라도, 실험 반복 비용이 눈에 띄게 줄었다는 점은 분명했다. 특히 이 프로젝트에서는 모델 구조를 바꾸는 것보다, 이런 병목을 먼저 줄이는 쪽이 더 직접적인 개선이었다.
추가로 정리한 부분
학습 속도만 본 것은 아니고, 추론과 제출 쪽도 같이 정리했다.
--resume기반 checkpoint 복원- S-Norm scoring 스크립트 정리
- cohort embedding 생성 분리
- 제출 파일 포맷 자동 감지
- row 수 검증
- timestamp 기반 zip 패키징
특히 제출 단계에서는 대규모 trial pair를 다루기 때문에, 누락이나 포맷 오류가 나면 그대로 제출 실패로 이어질 수 있었다. 그래서 이 부분은 “편의 기능”보다 안정성 쪽에 더 가까웠다. 학습부터 제출까지 end-to-end로 이어지는 구조도 파일 기준으로 확인된다.
내가 맡은 부분
- 원본 코드베이스 병목 확인 및 최적화
- DataLoader worker / pin memory / persistent workers 조정
- forward 내부 fbank 추출 병렬화
- checkpoint / resume 정리
- S-Norm scoring 스크립트 및 cohort 생성 파이프라인 정리
- 제출 검증 및 패키징 자동화