3 minute read

감정 실험의 변형(modality × context × prosody) 전체셋을 마감하고, 응답 task의 입력 paradigm 결정과 평가축까지 확정. log-15에서 톤 맵핑·TTS 96/112를 만들어 두었고, 이제 그 위에서 설계를 마무리하는 단계.


응답 task의 입력 paradigm (A)

응답 생성 task에서 모델에 무엇을 입력으로 줄지를 두고 두 paradigm을 비교했다.

Paradigm 입력 모델 출력 사람 응답 reference 추가 비용
A: turns[:-1] 입력 마지막 발화 제외 마지막 발화 생성 turns[-1] = 데이터셋 사람 응답 audio respond 신규 TTS 56×2=112콜
B: 전체 turns 입력 N턴 전체 N+1번째 발화 생성 없음(N+1 발화는 데이터셋에 없음) 0

처음에는 비용을 우선해 B로 결정했다. 그러나 A의 사람의 turn[-1]을 LaaJ에 후보로 추가할 수 있음이 연구의 핵심을 살린다는 판단이 들었다. 모델 응답들끼리만 비교하면 “어떤 모달리티 입력이 더 좋은 응답을 만드는가”는 답할 수 있지만, “한국어 정서 응답에서 모델이 사람을 이기는가/사람과 비슷한가” 라는 흥미로운 질문은 살펴볼 수 없게 된다. paradigm A는 그 anchor가 자동 제공되는 상황이 되기도 하기 때문에 돌려야 할 준비해야 할 데이터는 많아지지만 가치가 있다고 보인다.

진행시 고려사항: 마지막 발화까지 포함된 음성을 새로 만드는 게 아니라(=B에 필요), 오히려 마지막 발화를 빼고 TTS해야 한다(=A 입력). 56샘플 × neutral/emotion 2종 = 112 wav, ≈2일 콜 분량. text·image의 turns[:-1] 변형은 비용 0이라 이미 만들어 둠.

→ 최종 A로 결정. 아래의 변형 정의·데이터 현황은 이 paradigm을 전제로 정리된다. audio respond TTS는 다음 세션에서 진행.


Variants 정의 (3가지 축)

대화의 전달 매체(modality), 상황 설명(context) 포함 여부, 그리고 task용 입력 컨텍스트 크기 — 세 축으로 변형을 나눈다.

modality text / image / audio
context (text·image만) bare(상황 제외) / ctx(상황 포함)
prosody (audio만) neutral / emotion
task 컨텍스트 classify(전체 대화) / respond(turns[:-1], paradigm A)

text·image는 생성 비용 0이라 ctx와 task 두 축 모두 두 버전을 다 만들고 실험은 bare부터 시작. audio는 ctx축을 만들지 않고(상황은 프롬프트 텍스트로 공통 제공), task 축만 두 버전 — paradigm A 입력(turns[:-1])용 wav를 새로 TTS해야 한다.

prosody 축(neutral/emotion)은 audio 안에서 운율 정보가 분류·응답에 영향을 주는지 보려고 유지. neutral은 “다음 대화를 자연스럽게 읽어줘”, emotion은 log-15 톤 매핑 테이블의 감정 톤 지시.


파일 컨벤션 (task별 서브폴더)

data/exp_c/artifacts/
  classify/                ← 전체 대화 (분류 task)
    {id}-text.txt          : 대화만
    {id}-text-ctx.txt      : [상황] + 대화
    {id}-image.png         : 대화만 PNG
    {id}-image-ctx.png     : [상황] + 대화 PNG
    {id}-neutral.wav       : 대화만 평이 TTS
    {id}-emotion.wav       : 대화만 감정 톤 TTS
  respond/                 ← turns[:-1] (응답 생성 task)
    {id}-text.txt
    {id}-text-ctx.txt
    {id}-image.png
    {id}-image-ctx.png
    {id}-neutral.wav       (※ 신규 TTS 콜 필요)
    {id}-emotion.wav       (※ 동상)

같은 파일명을 task 폴더로만 분리. 세 generator 모두 sample_pool.json을 읽고 두 task에 대해 각각 생성, 기존 파일은 skip. 변형 추가는 image/text는 VARIANTS dict에 한 줄, audio는 _generate_tts의 분기 추가.


데이터 현황 (4/27 시점)

구분 샘플 classify (전체 대화) respond (turns[:-1])
기쁨 10 text·ctx·image·image-ctx·neutral·emotion 6×10 ✓ text·ctx·image·image-ctx 4×10 ✓ / wav 0 ❌
슬픔 10 동상 ✓ 동상
분노 10 동상 ✓ 동상
중립 10 동상 ✓ 동상
8 동상 ✓ 동상
8 동상 ✓ 동상
56 336/336 ✓ 224/336 (text/image 224 ✓, audio 112 미생성)

audio respond 112개는 다음 세션에서 TTS 콜로 생성 예정.


Tasks

분류 (classify)

6지선다(기쁨/슬픔/분노/중립/정/한)를 골라내는 단답 task. 출력은 text only.

  • 평가: 정답률(accuracy) — sample_pool의 category 필드와 비교
  • 4 variants 사용: text-bare / image-bare / audio_neutral / audio_emotion
  • Kanana 콜 예산: 4콜/샘플 × 56샘플 = 224콜 (≈4일 분량)

응답 생성 (respond)

artifacts/respond/ 입력(turns[:-1])을 받아 데이터셋의 마지막 발화 자리(turn[-1])에 들어갈 응답을 자유 텍스트로 생성. 출력은 text + audio.

  • 입력: turns[:-1] (modality별로 text·image·audio 형태)
  • 모델 출력: text 응답 + audio 응답 (HCX는 text only)
  • 평가: LLM-as-a-judge pairwise — 후보군에 사람 응답(turn[-1])도 포함해서 모델 vs 사람 vs 모델 간 비교
  • 4 variants 사용
  • HCX의 audio 차원은 결측 처리

분리 vs 통합

분류와 응답 생성을 한 콜에 묶어 출력할 수도 있지만(콜 절반), 평가가 섞여서 깔끔하지 않다. 분리해서 각각의 정답률과 응답 품질을 독립적으로 측정한다.


모델 라인업

모델 파라미터 한국어 특화 adapter audio in audio out
Kanana-1.5-o 11.6B kanana_client.py (REST)
HCX-SEED-Omni 8B experiments/exp_c/adapters/hcx.py ✗ (디코더 미공개)
Qwen2.5-Omni 7B .../qwen.py
MiniCPM-o 2.6 8B .../minicpm.py

비교 모델은 모두 4×RTX3090 local에서 돌고, exp_a 어댑터를 상속해 INSTRUCTION만 감정 task용으로 교체. parallel_runner로 4-GPU 분산 실행 패턴은 exp_a와 동일하게 가져갈 예정.


Next steps

  1. 분류 풀 배치 — 13~17샘플/일, 4일 안에 56샘플 완주
  2. audio respond TTS 112개 — paradigm A 입력 (turns[:-1] 음성), 2일 분량 콜
  3. 응답 생성 runnerRESPOND_INSTRUCTION 가다듬기, audio output 받기, 사람 응답 후보 결과 JSON에 같이 저장
  4. LaaJ 프롬프트 설계 — pairwise 비교 기준(공감 정도, 자연스러움, 한국어 운율 적합성 등). 후보군: Kanana / HCX / Qwen / MiniCPM / 사람
  5. 비교 모델 어댑터 확장 — exp_c용 Kanana 어댑터 추가, parallel_runner 패턴 도입

분류 결과부터 모이는 대로 patterns 보면서 RQ1·RQ3에 대한 예비 시그널을 확인하고자 한다.