1P by GN⁺ | ★ favorite | 댓글 1개
  • 범용 LLM이 과한 특수 작업에서는 Llama-2를 직접 파인튜닝해 더 작고 저렴한 모델로 품질·비용·지연 시간을 함께 개선할 수 있음
  • Llama-2 13B는 파인튜닝 후 ViGGO 함수 표현 정확도가 58%→98%, SQL 생성이 42%→89%, GSM8k가 28%→47%로 상승함
  • ViGGO와 SQL 생성처럼 출력 형식이 중요한 작업에서는 작은 Llama-2 모델이 GPT-4보다 나은 결과를 냈지만, 수학 추론에서는 GPT-4 수준에 도달하지 못함
  • 실험은 Ray Train, Ray Data, DeepSpeed, Accelerate 기반 스크립트로 진행됐고, 7B·13B는 16xA10G, 70B는 32xA10G에서 학습함
  • 성능 향상의 핵심은 모델 크기보다 데이터 품질과 평가 파이프라인이며, 프롬프트 엔지니어링과 파인튜닝의 비용·품질 trade-off를 작업별로 비교해야 함

세 가지 작업에서 본 파인튜닝 효과

  • GPT-4, Claude-2 같은 대형 범용 모델은 빠른 프로토타이핑에 유용하지만, 지원 티켓 요약·분류처럼 범위가 좁은 요구에는 비용과 성능 면에서 과할 수 있음
  • 실험은 Llama-2 모델을 세 가지 실제형 작업에 맞춰 풀 파라미터 파인튜닝했을 때의 개선 폭을 비교함
    • ViGGO: 비정형 텍스트에서 함수형 표현 추출
    • SQL-create-context: 자연어와 CREATE TABLE 문맥에서 SQL 생성
    • GSM8k: 초등 수준 수학 문제 풀이
  • Llama-2 13B 기준 정확도 변화는 다음과 같음
    • ViGGO 함수 표현: 58% → 98%
    • SQL 생성: 42% → 89%
    • GSM8k: 28% → 47%
  • ViGGO와 SQL 생성에서는 작은 Llama-2 모델이 GPT-4보다 좋은 결과를 냈고, GSM8k 같은 수학 추론 작업에서는 파인튜닝 후에도 GPT-4 성능에 미치지 못함

파인튜닝 방식과 학습 인프라

  • 세 작업 모두 표준 풀 파라미터 파인튜닝을 사용함
    • 다음 토큰 예측 방식으로 학습함
    • 모델의 모든 파라미터가 그래디언트 업데이트 대상임
    • LoRA나 일부 transformer block 고정 방식은 실험 범위에서 제외됨
  • 실험 스크립트는 Ray Train, Ray Data, DeepSpeed, Accelerate 위에 구축됨
    • Llama-2 7B, 13B, 70B 실행을 지원함
    • Ray Train의 TorchTrainer가 여러 워커 프로세스와 GPU 리소스로 학습 루프를 분산함
    • 데이터 샤딩은 Ray Train이 처리하고, 각 워커는 session.get_dataset_shard("train"), session.get_dataset_shard("valid")로 할당된 데이터 조각에 접근함
  • 모델 샤딩은 DeepSpeed ZeRO stage 3와 optimizer state offloading으로 처리함
    • 모델 조각이 여러 워커에 나뉘어 있어 체크포인트 저장처럼 전체 모델 접근이 필요할 때는 accelerator.unwrap_model(model)로 모델을 풀어야 함
  • 계산 자원은 다음과 같음
    • 7B·13B: 16xA10G
    • 70B: 32xA10G, 4대의 g5.48xlarge 인스턴스
    • Ray를 사용하면 풀 파라미터 파인튜닝에 반드시 A100이 필요하지 않음
  • 학습은 최대 10 epoch까지 수행했고, 검증 세트에서 perplexity가 가장 낮은 체크포인트를 선택함

특수 토큰으로 입력·출력 구조 고정

  • 파인튜닝 데이터는 명령문 프롬프트 대신 특수 토큰으로 작업 구조를 표현함
    • 예: <START_Q>{question}<END_Q><START_A>{answer}<END_A>
  • 특수 토큰은 모델이 입력과 출력 구간을 구분하고, 출력 중단 지점을 명확히 학습하도록 도와줌
    • 예시에서는 <END_A>를 stopping token으로 정의해 작업 완료 시 출력을 멈추게 함
  • Llama tokenizer는 기본적으로 32,000개 토큰 ID를 출력함
    • 네 개 특수 토큰을 추가하면 32,004개 ID를 출력함
    • <START_Q>는 32000, <END_Q>는 32001 같은 방식으로 새 ID가 부여됨
  • 스크립트는 tokenizer.add_tokens(special_tokens, special_tokens=True)로 특수 토큰을 추가하고, model.resize_token_embeddings(len(tokenizer))로 새 학습 파라미터를 만듦

ViGGO: 비정형 텍스트를 함수형 표현으로 변환

  • ViGGO는 원래 속성-값 기반 함수형 표현을 자연어 텍스트로 바꾸는 영어 데이터셋이며, 실험에서는 방향을 뒤집어 비정형 텍스트를 구조화된 함수형 표현으로 변환함
    • 도메인은 비디오 게임 의견임
    • 결과 표현은 인덱싱과 후속 애플리케이션에 사용할 수 있음
  • 모델은 문장에 맞는 함수와 속성 값을 생성해야 함
    • 함수 후보에는 inform, request, give_opinion, confirm, verify_attribute, suggest, request_explanation, recommend, request_attribute가 포함됨
    • 속성 후보에는 name, release_year, esrb, genres, platforms, available_on_steam, has_linux_release, has_mac_release, specifier, rating, player_perspective, has_multiplayer, developer, exp_release_date 등이 포함됨
  • 예시 입력 What's a really fast-paced game with multiplayer that you like to play?의 기대 출력은 request(has_multiplayer[yes], specifier[fast-paced])
  • 일반 모델은 의도한 출력 형식을 잘 따르지 못했고, 긴 입력 컨텍스트 때문에 출력 생성보다 입력 처리 시간이 커지는 문제가 있음
  • 이 작업은 복잡한 논리 추론보다 패턴 인식과 기본 언어 이해가 중심임
    • 필요한 사실이 모두 입력에 포함된 grounded task임
    • few-shot 프롬프트가 도움이 된다는 점은 작은 Llama-2 모델도 파인튜닝으로 개선될 수 있다는 신호로 쓰임

ViGGO 평가와 결과

  • 평가는 완전한 문자 일치만 사용하지 않음
    • 출력 함수가 올바른지 확인함
    • 속성 타입이 올바른지 확인함
    • 함수 안 속성이 정해진 우선순위 순서를 따르는지 확인함
  • GPT, Llama-2-chat 같은 instruction-following 모델에는 프롬프트에 속성 순서 규칙이 명시됐기 때문에 해당 규칙을 따라야 하는 조건으로 평가함
  • 평가 속도를 높이기 위해 Ray의 batch inference API와 Anyscale의 Aviary를 함께 사용함
    • LLM 생성과 후처리를 연결하고 여러 머신에 분산함
  • 7B와 13B 모델은 파인튜닝 후 정확도가 크게 향상됨
    • GPT-4는 속성 우선순위를 평가에 포함하면 정확도가 크게 떨어짐
    • 파인튜닝 모델은 항상 우선순위를 따랐고, 이 제약을 추가해도 정확도가 변하지 않음
  • ViGGO 결과는 구조화된 형식이 필요한 작업에서 파인튜닝이 안정적이고 효율적인 수단이 될 수 있음을 보여줌
    • 단순 regex나 JSON 형식 맞추기가 아니라, 포함할 인자를 판단하고 포함된 인자의 순서까지 지켜야 하는 작업임
    • 7B·13B 모델로 얻은 결과라 GPT-4 endpoint 호출보다 서빙 비용이 낮을 수 있음

SQL 생성: 자연어와 테이블 문맥에서 쿼리 만들기

  • SQL 생성 작업은 자연어 질의와 SQL CREATE TABLE 문을 입력받아 실행 가능한 SQL 쿼리를 생성하는 것임
  • 사용 데이터셋 b-mc2/sql-create-contextWikiSQLSpider를 결합한 Hugging Face 데이터셋임
    • 각 데이터 포인트는 자연어 질의, SQL CREATE TABLE 문, 대응되는 SQL 쿼리로 구성됨
    • 전체는 78,577개 데이터 포인트임
  • 데이터셋에는 정답 SQL의 문제가 있었음
    • CREATE TABLE에서는 정수 속성이 VARCHAR로 표시됐지만, SQL 쿼리에서는 정수처럼 처리되는 경우가 많았음
    • 정수 속성이라고 가정한 SQL 쿼리를 모두 제거해 데이터셋을 약 70k에서 45k로 줄임
  • 이 작업도 자연어를 SQL이라는 구조화 표현으로 바꾸는 문제라 파인튜닝에 적합함
    • ViGGO와 달리 올바른 실행 결과를 내는 SQL이 여러 개일 수 있어 더 모호함

SQL 평가와 결과

  • SQL 생성 평가는 단순 문자열 비교가 부적절함
    • 문자 단위 비교는 false negative를 많이 만들 수 있음
    • AST 비교도 변수명 순서 같은 요소에 민감할 수 있음
    • 가장 신뢰할 수 있는 방법은 가짜 데이터셋에서 코드를 실행하고 출력이 같은지 비교하는 것임
  • 실험에서는 OpenAI GPT-3.5 endpoint로 수백 개 예시에 대한 단위 테스트용 가짜 테이블을 생성함
    • GPT-3.5가 질문, 테이블 스키마, 정답을 보고 10개 데이터 포인트의 가짜 테이블을 만듦
    • sqlglot.executor.execute로 정답 SQL과 모델 SQL을 실행해 결과를 비교함
  • GPT-3.5가 생성한 데이터 테이블 품질을 확인하기 위해 정답 SQL을 먼저 실행함
    • 결과 테이블이 비어 있거나 원래 테이블과 같은 길이면 해당 예시를 버림
    • 이 과정에서 GPT가 만든 데이터 테이블의 약 50% 가 필터링됨
  • 파인튜닝한 Llama-2 7B와 13B는 70B-chat과 GPT-4보다 높은 성능을 냄
    • Llama chat 모델의 흔한 오류는 프롬프트 지시와 달리 SQL을 <SQL> 태그 안에 일관되게 넣지 않는 것이었음
    • 이 문제는 7B·13B chat 모델에서 70B보다 더 흔함
  • SQL 데이터셋의 일부 자연어 질의는 완벽한 영어가 아니었고, 이런 노이즈가 GPT-4 결과에 영향을 줬을 가능성이 있음
    • 파인튜닝 모델은 데이터셋의 특이한 버릇에도 빠르게 적응함

GSM8k: 구조 학습보다 어려운 수학 추론

  • GSM8k는 수학 추론과 이해 능력을 평가하는 표준 학술 벤치마크임
  • 이전 두 작업이 주로 구조 학습이었다면, GSM8k는 모델이 수학 문제를 풀기 위한 추론 과정을 얼마나 개선할 수 있는지 확인하는 작업임
  • 예시 문제는 4월에 48개를 팔고 5월에 그 절반을 팔았을 때 총 판매량을 묻는 형태이며, 정답은 중간 계산과 함께 #### 72 형식으로 끝남
  • 현재 LLM은 최종 답만 내부적으로 계산해 바로 내기보다, 출력 일부로 사고 과정을 생성해야 이후 토큰 생성이 논리적 과정에 기반할 수 있음
  • 이 작업은 단순 계산뿐 아니라 전제에서 중간 결론을 거쳐 최종 답으로 가는 논리적 chain of thought가 필요함

GSM8k 평가 방식과 기준선

  • 평가에는 모델 출력에서 최종 정답을 안정적으로 추출하는 방법이 필요함
  • 일반 언어 모델은 원하는 출력 형식을 일관되게 따르지 못할 수 있어 자동 평가가 어려움
    • 이를 위해 OpenAI function calling API를 사용함
    • gpt-3.5-turbo-0613이 다른 모델의 생성 결과에서 최종 정수 답을 추출하도록 report_answer 함수를 호출함
    • 예를 들어 모델이 “The answer is four”라고 답해도 4로 파싱할 수 있음
  • 이 방법은 데이터셋 정답에서 테스트해 유효성을 확인했지만, 평가에 OpenAI 토큰 비용이 든다는 단점이 있음
  • 파인튜닝 모델은 목표 답변 패턴을 빠르게 학습해 오답일 때도 출력 구조가 예측 가능함
    • 파인튜닝 모델 평가는 #### {answer} 정규식으로 처리해 OpenAI endpoint 후처리를 피함
  • 기준선은 다음과 같음
    • 논문에 공개된 base pre-trained 모델의 8-shot prompting 결과
    • Meta가 RLHF로 범용 assistant가 되도록 학습한 Llama-2 chat-tuned 변형들에 대한 여러 prompt-engineered 템플릿

GSM8k 결과와 2단계 파인튜닝

  • base 모델 파인튜닝은 GSM8k 성능을 일관되게 높였지만, chat-tuned 모델보다 크게 나은 결과를 항상 만들지는 않음
    • chat 모델은 chat-tuning 과정에서 수학 예시로 학습됐을 가능성이 있어 base 모델보다 정확도가 높았음
  • 파인튜닝 모델에 프롬프트를 넣는 방식이 항상 base 모델보다 좋은 결과를 내지는 않음
    • 예를 들어 Llama-2-70B-chat은 8-shot 예시 프롬프트를 넣은 base 모델보다 낮을 수 있음
    • 파인튜닝 모델은 8-shot prompted base 모델보다 일관되게 더 좋았음
  • 서빙 비용 측면에서는 파인튜닝 모델이 유리할 수 있음
    • 프롬프트 기반 방식은 요청마다 프롬프트 토큰 비용이 붙음
    • 파인튜닝 모델은 사실상 질문 토큰 수만 비용에 반영됨
  • GSM8k 학습 데이터는 약 8k개로 상대적으로 작아, Llama-13B의 잠재력을 충분히 끌어내기 어렵다고 판단함
  • Llama-13B base 모델을 먼저 MathQA로 파인튜닝한 뒤 GSM8k로 다시 파인튜닝하는 2단계 방식이 추가 개선을 냄
    • GSM8k만 사용한 파인튜닝은 base 대비 10%p 개선됨
    • MathQA 후 GSM8k를 사용한 2단계 파인튜닝은 초기 파인튜닝 결과에서 추가 10%p, base 대비 총 20%p 개선됨
  • MathQA는 30,000개 질문/답변 쌍으로 구성됐지만 GSM8k보다 노이즈가 많고 구조가 다름
    • 답변 품질이 낮고, 최종 답은 multiple choice 형식임
    • 그래도 2단계 파인튜닝은 MathQA를 활용해 GSM8k 최종 결과를 개선하는 데 효과적이었음

실무 적용에서 봐야 할 기준

  • GPT-4, Claude-2 같은 폐쇄형 모델은 프로토타이핑과 초기 가치 검증에 강하지만, 프로덕션 LLM 앱 운영에 항상 충분하지는 않음
  • niche task용 LLM 파인튜닝은 프라이버시뿐 아니라 지연 시간, 비용, 품질 측면에서 가치가 있을 수 있음
    • ViGGO와 SQL 예시에서는 품질 면에서도 GPT-4보다 좋은 결과가 나옴
  • 파인튜닝에서 중요한 초점은 인프라 세부 구현보다 데이터 수집과 평가 파이프라인 구축임
    • 평가 파이프라인은 여러 해법의 trade-off를 비즈니스 요구에 맞춰 비교하는 기반이 됨
  • 실험은 Anyscale fine-tuning 및 serving 플랫폼과 Anyscale Endpoints를 사용해 수행됨
  • 동일한 프로세스는 자체 데이터와 자체 클라우드에서 반복할 수 있도록 Ray 위의 Anyscale fine-tuning 및 serving 솔루션으로 구성됨

댓글과 토론

Hacker News 의견들
  • 몇 주 전 코딩 라이브 스트림에서 자체 데이터셋으로 Llama 2 미세조정하는 내용을 많이 다뤘고, Colab 단일 GPU에서 진행했음
    내 경우 데이터셋은 내 코드였음.
    Fine-tuning Llama stream: https://www.youtube.com/watch?v=TYgtG2Th6fI&t=2282s
    QLoRA 미세조정 세션도 몇 개 더 있고, 8년차 소프트웨어 엔지니어가 최근 머신러닝으로 넘어오며 독학한 관점에서 개념을 설명함
    QloRa fine-tuning stream: https://www.youtube.com/watch?v=LitybCiLhSc&t=4584s
    개인 프로젝트와 현재 진행 중인 AI 기반 스타트업에서 어떻게 접근하는지 최대한 쉽게 풀어내려 하고 있음. 가장 작은 웹 개발용 LLM을 미세조정하는 시리즈도 반응이 괜찮아 보이며, 스트리밍은 한 달 정도 했고 앞으로 더 많이 올릴 예정임

    • RAG와 미세조정을 언제 각각 쓰는 게 맞는지 일반적인 판단 기준이 궁금함
      미세조정 모델을 나눠 갖는 방식도 잘 이해가 안 됨. Terraform LLM, SQL LLM, Python LLM이 따로 필요한지, 아니면 그냥 “코드” LLM 하나면 되는지 궁금함
    • “소스 자료를 이 디렉터리에 넣고, 버튼을 누른 뒤, 그 내용과 채팅한다” 수준의 단순한 앱/모듈/라이브러리가 정말 필요함
      구현 세부사항이 너무 많이 필요해서 의미 있는 사용처가 아닌 이상 접근성이 떨어짐. privateGPT가 천천히 그 지점까지 갈 것 같긴 함
    • 좋았고, 미세조정용 커스텀 데이터셋 준비에 대한 시리즈도 해주면 좋겠음
      다른 튜토리얼들이 많이 건너뛰는 부분임. 특히 안전성, 정확도 같은 서로 다른 목표에 따라 어떻게 준비하는지가 궁금함
    • GPU 하나로 가능한가? 3060 하나로도 현실적인지 궁금함
  • Llama 2에서도 같은 문제를 겪고 있음. 원하는 텍스트만 출력하게 만드는 게 거의 불가능하고, 항상 응답 앞뒤에 뭔가를 덧붙임
    이 문제를 고칠 수 있는 프롬프트 기법이 있는지 궁금함

    • 더 나은 모델을 쓰는 게 좋음
      airoboros는 백틱, 설명 등을 피하고 코드만 출력하게 하는 PLAINFORMAT 토큰을 지원함
      https://huggingface.co/TheBloke/airoboros-l2-70B-GPT4-2.0-GG...
    • Llama-2-chat 모델들은 이런 식으로 과하게 미세조정되어 있음. 퓨샷 프롬프팅을 시도해볼 수는 있지만 원하는 출력을 보장하지는 못함
      보장하려면 작은 데이터셋, 대략 1천 개 정도로 미세조정한 뒤 거기서부터 개선하는 편이 가장 좋음
    • 목표에 따라 다르지만, RLHF된 모델 대신 기본 LLaMA2 모델을 미세조정해서 특정 출력 형식을 재현하는 데 성공했음
      내 사용처는 창작 글쓰기보다 텍스트에서 정보 추출/종합을 하는 단순한 작업이었음. 기본 모델이 모든 작업에 잘 맞지는 않을 수 있음
    • 모델이 항상 답변이나 코드를 content 문자열이나 JSON 안에 출력하도록 프롬프트를 주면 됨
      JSON이라면 시작과 끝을 식별할 수 있으니, JSON 바깥의 내용은 제거하면 됨
  • 이런 글이 나와서 반가움. 온라인에서 모델 커스터마이징 논의가 너무 많았는데, 이 글은 잡음을 꽤 잘 걷어냄
    평가 방법론도 마음에 들고 글도 잘 쓴 편으로 보임

  • LoRA와 양자화 학습이 더 진지하게 다뤄지지 않는 게 이상함. 훨씬 저렴하고 시간도 덜 들며, 꽤 좋다는 근거도 많음
    나중에 해보는 부가 옵션처럼 밀어둘 대상은 아니라고 봄

  • NER 비슷한 작업이 가장 좋은 성능을 낸 걸 보니 반가움. 미세조정한 BERT 모델과 비교하려고 비슷한 테스트를 막 해보려던 참이었음
    이 작업의 학습 비용이 어느 정도인지 궁금함

    • 글의 공동 저자임. ViGGO 학습 데이터는 약 5.1천 행이고, 블록 크기 512로 학습했음
      블록 크기는 낮출 수도 있지만 코드를 바꾸지 않는 게 쉬워서 그대로 뒀음. 7B는 16xA10G에서 에포크당 약 15분, 13B는 약 25분 걸렸음. 따라서 온디맨드 비용은 에포크당 7B가 약 $7.2, 13B가 약 $12임. 이 값은 학습에 쓴 시간만 기준이며 클러스터 시작/종료 시간은 포함하지 않음
    • 좋은 질문임. 10에포크가 얼마나 걸렸는지 적어줬다면 비용을 계산할 수 있었을 텐데 아쉬움. 더 좋게는 시간과 비용을 같이 올려줬으면 했음
      7B와 13B에는 16xA10G를, 70B에는 32xA10G를 4개의 g5.48xlarge 인스턴스에 나눠 사용했다고 되어 있음. Ray를 쓰면 이런 모델의 전체 파라미터 미세조정을 위해 A100을 확보할 필요가 없고, 같은 과정을 각 작업마다 반복함. GSM8k 데이터셋에서는 문맥 길이 512, 에포크당 유효 토큰 370만 개 기준의 예시 실행을 보여줌
      최대 10에포크까지 학습하고, 검증 세트에서 최소 퍼플렉시티를 보인 체크포인트를 선택했다고 함
  • 한 가지 어려움은 충분히 큰 커스텀 데이터셋을 만들려면 소규모 군대 같은 인력이나 아주 강한 기존 모델이 필요하다는 점임
    결국 OpenAI를 써야 할 가능성이 큰데, OpenAI로 다른 모델의 학습 자료를 생성하는 건 약관 위반임. 이걸 두고 소송까지 간 적이 있는지 궁금함. 그냥 불공정하다고 보고 무시하는 건가?

    • 모든 작업에 해당하는 건 아님. 많은 자연어 처리 작업에서는 기존 데이터를 LLM 형식에 맞게 다시 포맷하기만 하면 됨
    • 약관을 무시하면 안 될 이유가 있나? 최악의 경우 접근 권한을 잃는 정도임
  • 요즘 NER 예시가 더 자주 보이는데, 그런 작업에 왜 spaCy를 쓰지 않는지 궁금함

    • spaCy는 다국어 학습 데이터에서 잘 작동하지 않고, transformers 계열보다 더 많고 더 이상한 방식으로 터지는 경우도 봤음
    • 비싼 모델로 데이터에 라벨을 붙인 다음, 교사/학생 방식으로 더 작은 모델인 SpaCy나 BERT를 학습시켜 비용과 속도를 잡는 방향으로 생각하고 있음
    • NER에는 미세조정한 BERT 계열 모델을 쓰고 있는데, 성능 비교는 해보고 싶음
  • Anyscale에서 일하고 있음
    이 블로그가 좋은 관심을 받은 것 같아서 Ray Summit에 넣을 계획임: https://raysummit.anyscale.com/agenda
    Ray Summit에서 어떤 종류의 콘텐츠를 더 보고 싶은지 아이디어가 있으면 알려주면 좋겠음

  • 350만 토큰 기준 7B는 1에포크에 약 14분, 13B는 1에포크에 약 26분이라고 되어 있음
    7B와 13B 모두 헤드 노드로 최소 1xg5.16xlarge, 워커 노드로 15xg5.4xlarge가 필요하다는데, AWS에서는 비용이 어느 정도인지 궁금함

  • M1 Ultra 64GB에서 Llama-2를 로컬 미세조정할 수 있는지 궁금함. 대부분 클라우드이거나 Linux에서 Nvidia CUDA를 쓰는 방식이라 참고할 만한 자료가 있으면 좋겠음

    • 아닐 것 같음. M1 Max 64GB를 쓰는데 일부 추론은 괜찮게 돌아감
      학습은 RunPod 크레딧을 조금 사서 하려 하고, 몇십 달러면 가능할 것 같음