트랜스포머·PEFT 2일 과정9장 · 모델 평가와 활용, QLoRA14 / 20← 이전목차다음 →MetaContents

9장. 모델 평가와 활용, QLoRA

실습 2 — 일반 질문으로 부작용 점검하기

말투 학습과 상관없는 일반 질문 세 개를 어댑터를 끈 모델과 켠 모델에 각각 묻습니다. 실습 1의 lora_model 과 6장의 chat 함수를 씁니다. 6~8차시의 준비 코드를 먼저 실행해 둡니다.

코드를 단계별로 따라가기 전에 실행 흐름을 한 장으로 봅니다. 반복 하나에 끄고 켜기가 들어 있는 짧은 흐름입니다.

실습 2 코드의 실행 흐름도. general_questions 에 수도, 덧셈, 끓는점 질문 세 개를 담고, 질문마다 disable_adapter 블록 안에서 before 답을, 블록 밖에서 after 답을 max_new_tokens=40 으로 만들어 앞 80 글자씩 찍는 반복을 세 번 돈다
단계하는 일반복과 조건핵심 한 줄
1일반 질문 세 개를 어댑터를 끄고 켜며 묻기for question in general_questions 세 바퀴, 바퀴마다 with lora_model.disable_adapter(): 로 끈 답 한 번, 켠 답 한 번before = chat(lora_model, question, max_new_tokens=40)
  • 흐름도 읽는 법: 실습 1 과 같습니다. 마름모 고리 한 바퀴가 질문 하나입니다.
  • 고리 한 바퀴의 일: 블록 안에서 before(학습 전)를, 블록 밖에서 after(학습 후)를 만든 뒤 찍습니다. 세 바퀴를 돌므로 chat 은 3 × 2 = 6 번 불립니다.
  • 실습 1 과 같은 스위치: 모델은 lora_model 하나뿐이고, with 블록이 끝나면 어댑터가 저절로 다시 켜집니다. 그래서 after 를 만들 때 따로 켜는 코드가 없습니다.

1단계. 끈 답과 켠 답 나란히 보기

사투리 연습을 마친 배우에게 은행 창구 대사를 시켜 보는 일입니다. 같은 질문을 연습 전(어댑터 끔)과 연습 후(어댑터 켬)로 한 번씩 묻습니다.

Python · GPU 필요 (출력은 RTX 3080 에서 실행한 결과)
# 학습에 사용하지 않은 일반 질문으로 기반 모델과 LoRA 모델의 답변을 비교합니다.
# 말투와 상관없고 정답이 분명한 질문 세 개(수도, 덧셈, 끓는점)
general_questions = ["대한민국의 수도는 어디인가요?", "3 더하기 5는 얼마인가요?", "물은 몇 도에서 끓나요?"]
for question in general_questions:
    with lora_model.disable_adapter():  # LoRA 어댑터를 잠시 끄고 기반 모델의 답변을 생성합니다.
        # chat(모델, 질문, max_new_tokens=40): 6차시의 생성 함수. do_sample=False 라 늘 같은 답이 나온다
        # max_new_tokens=40: 새로 만들 토큰을 40개까지로 줄여 빨리 끝낸다
        before = chat(lora_model, question, max_new_tokens=40)  # 기반 모델 답변을 생성합니다.
    # with 블록을 나왔으므로 어댑터가 다시 켜진 상태
    after = chat(lora_model, question, max_new_tokens=40)  # LoRA 적용 답변을 생성합니다.
    # [:80]: 답을 앞 80글자까지만 보여 준다
    # 결과: 학습 전은 존댓말 설명, 학습 후는 "서울이지. 네 지름길이라니." 처럼 짧은 반말과 비꼼
    print(f"Q: {question}\n  학습 전: {before[:80]}\n  학습 후: {after[:80]}\n")
출력
Q: 대한민국의 수도는 어디인가요?
  학습 전: 대한민국의 수도는 서울입니다.

서울은 대한민국의 가장 큰 도시로, 1982년에 설립된 서울특별자치도를 중심
  학습 후: 서울이지. 네 지름길이라니.
Q: 3 더하기 5는 얼마인가요?
  학습 전: 3 더하기 5은 8입니다.

계산식을 작성하면 다음과 같습니다:

3 + 5 = 8

이 계산 결과를 확인해 보시면 됩니다.
  학습 후: 더하기 해서 네 속은 변하지 않아.
Q: 물은 몇 도에서 끓나요?
  학습 전: 물은 대부분의 경우 물리적으로 빠르게 움직이지 않습니다. 그러나 일부 물질들은 매우 가속력 있는 속도로 움직입니다:

1
  학습 후: 천문관에 다다르면 물이 뜯어질 거예요.

학습 후의 답은 세 개 모두 페르소나 말투입니다. 수도 질문은 "서울이지."로 정답을 말하지만, 덧셈 질문은 정답 8 대신 "더하기 해서 네 속은 변하지 않아."라고 비꼽니다. 학습 데이터에 질문에 직접 답하지 않고 비꼬는 예시가 많기 때문입니다. 끓는점 질문은 어댑터를 끈 기반 모델도 엉뚱하게 답합니다. 이것은 0.5B 모델 자체의 한계이고, 어댑터의 부작용과는 나눠서 봐야 합니다.

이 실습이 뜻하는 것

은행 창구에서도 사투리가 튀어나오는지 확인했습니다. 연습한 말투가 연습하지 않은 장면까지 번진 것이 보입니다. 어댑터를 끈 답과 켠 답을 나란히 놓았기 때문에, "어댑터 탓"인지 "원래 모델의 한계"인지를 가를 수 있었습니다.

단계출력뜻
1단계수도: 둘 다 서울정답은 지켰지만 말투가 번졌다
1단계덧셈: 끔은 8, 켬은 비꼼어댑터의 부작용
1단계끓는점: 둘 다 엉뚱함기반 모델부터 약한 질문

한 줄 요약: 좁은 데이터로 학습한 어댑터는 학습 목표 밖의 질문까지 바꿉니다.

코드 설명

  • general_questions 는 말투와 상관없고 정답이 분명한 질문입니다. 정답이 분명해야 "나빠졌는지"를 판단할 수 있습니다.
  • with lora_model.disable_adapter(): 안에서 만든 before 가 학습 전 답, 블록 밖에서 만든 after 가 학습 후 답입니다. 모델은 하나뿐입니다.
  • chat(..., max_new_tokens=40) 은 6장의 기본값 80 보다 짧게 끊어 빨리 비교합니다. before[:80] 은 화면에 찍을 때만 자릅니다.
  • 실무에서는 일반 질문에 바르게 답하는 예시를 학습 데이터에 섞거나, epoch 과 학습률을 줄이거나, 필요할 때만 어댑터를 켜서 대응합니다.
← 이전 절9장 · 실습 1 — 평가 데이터로 학습 전후 손실 비교하기다음 절 →9장 · 실습 3 — 저장한 어댑터 불러오기, 끄고 켜기, 병합하기