2025.05.29 검토항목 계획 관련 내용 추가, 2차 검토항목 언급 추가
어쩌다보니 캡스톤 프로젝트를 조금 일찍 진행하게 되었다. 단독 개발(개발자 구하는 중이니 많관부)을 맡게 되어 당분간은 서버 개발기를 올리게 될 것 같다. 주제는 전체적인 방향성은 잡혀있으나, 아직 세부 기획은 조율 중이다. 따라서 후에 고도화하는 것을 염두에 두고 필수 기능들을 세부 기획과 함께 병행 작업하기로 했다.
요구사항 및 기술 검토 항목 작성
주제: 입력된 정보를 바탕으로 정보를 재가공하고 이를 바탕으로 이미지를 생성한다.
본격적인 개발에 들어가기 전에 주제가 가능한지, 또 얼마나 걸리는지 파악해보기 위해 우선 기능단위로 요구사항을 간단히 정리하고, 기술 검토 항목을 작성했다.
필수 요구사항
- 음성 데이터를 입력 받아야 한다.
- 데이터를 LLM을 이용해 가공한다.
- 데이터를 이미지로 생성한다.
- 음성 → 텍스트 → 이미지의 processing 시퀀스가 보장되어야 한다.
고려할 내용을 좀 더 세부적으로 고민해보았다.
- 음성 데이터를 수집 - 데이터 포맷/수집방법(interval/실시간)
- 음성 데이터를 텍스트로 변환 - TTS 라이브러리 검토/성능(시간/정확도)
- 텍스트를 바탕으로 LLM 처리 - LLM 모델 검토/프레임워크 검토/성능(시간/정확도)
- 음성 → 텍스트 → 이미지 + 응답 - state 관리/히스토리저장 등등…
이외에 다소 후순위지만 검토해야할 내용은 아래와 같았다.
- AI 서버가 설치될 물리적 환경(컴퓨터 성능, 컴퓨터의 물리적 위치 등)
- AI 파인튜닝(물론 중요하지만 당장은 전체 I/O을 구현하는걸 최우선으로 잡았다.)
1차 검토에서는 기능을 구현할 수 있는 라이브러리를 우선적으로 확인했다. 해당 기술 스택이 실제 요구 사항을 만족할 수 있는지, 그리고 프로젝트에 어떻게 통합하여 사용할 수 있는지에 대한 방향성도 함께 점검했다.
- 무료 라이센스일 것(혹은 무료 플랜이 있거나 저렴할 것)
- 파이썬을 지원할 것
- 로컬에서 실행가능할 것(AI모델)
가장 중요하게 고려한 요소는 money money해도 라이선스 비용(절대 무료일 것)이었다… 돈이 없어.
세부적인 성능검토는 서버 설계까지 기간이 남아있어 병행하게 될 것 같다. 팀에 인원이 있다면 이런 부분들은 진작 빠르게 넘어가지 않았을까 하는 아쉬움이 있다. 이미지 생성 검토 항목은 예경씨께서 주로 담당하기로 했고, 진행중이다.
(5월 29일자 업데이트: 28일자에 회의에서 새로운 방안을 제시, 해당 내용을 바탕으로 검토 항목을 다시 세웠다. )
1차 검토 항목
검토 환경
- gpu: gtx 1070, cpu: i5 사용
- os: window 10
1. STT 라이브러리 검토 및 테스트
- 사용 라이브러리: whisper STT
- 단/장문으로 STT 변환 테스트
- 단/장문 + 소음으로 STT 변환 테스트
- 다개국어(영어+한국어)로 STT 변환 테스트
2. lLama 검토 및 테스트
- 최초 설치 및 실행 확인
- python으로 api 응답 테스트
- 파인튜닝 및 튜닝 모델 공유 방법
- 대화 내용 메모리 저장 및 이어나가는 방법 검토
3. Speaker Diarization 라이브러리 검토(pyannote.audio, NVIDIA NeMo)
- diarization 라이브러리 검토 및 테스트
- diarization + whisper 연계하여 테스트
4. whisper + speechbrain + llama 파이프라인 통합하여 테스트
- 1개로 떨궈진 짧은 오디오로 테스트
- 오디오 길이별 테스트
- streaming 처리 가능 여부 테스트
검토결과
STT 라이브러리 검토 및 테스트
Whisper, FFmpeg 라이브러리를 비교했다. 근데 gpt한테 속았다(라이브러리 추천해달라함)... Whisper를 사용하기로 했다.
| 항목 | Whisper | FFmpeg |
| 목적 | 고성능 음성 → 텍스트 변환 | 음성 인코딩/디코딩 및 전처리 |
| 특징 | OpenAI 제공, 로컬 추론 가능, 다국어 지원 | STT 기능 자체는 없음 (전처리용으로 사용됨) |
| 활용도 | 실질적인 STT 처리 담당 | Whisper용 음성 포맷 전처리 등 보조 역할 |
- 라이브러리: whisper
+ 기획 고려 사항 - 음성 데이터를 수집할 할 때 interval하게 수집 vs start-end 전체를 수집
+ 추가 검토 항목 - 웹프론트에서 STT 수행(지원 api추가 검토) vs 서버에서 STT 수행
+ 추가 검토 항목 - 더 좋은 gpu환경에서 성능 테스트
lLama 설치 및 테스트
LLM 모델은 라이브러리 조건 3가지 모두 충족 가능한 lLama로 자연스럽게 좁혀졌다. 따라서 lLama의 응답 처리 부분을 중점으로 Ollama를 테스트했다.
- 버전: lLama 3.2
- 배포환경: Ollama
- 라이브러리: requests
Ollama로 로컬에 lLama를 배포하여 api 인터페이스로 호출해보는 과정을 확인해보았다. 차후 FastAPI 백엔드에서 Ollama를 통합하여 활용할 예정이다.
api 호출 예시
import requests
url = "http://localhost:11434/api/generate"
data = {
"model": "llama3.2",
"prompt": "오늘 날씨는 어때?",
"stream": False
}
response = requests.post(url, json=data)
if response.status_code == 200:
result = response.json()
print("모델의 답변:", result['response'])
else:
print("오류 발생:", response.status_code, response.text)

+ 기획 고려 사항 - 모델 튜닝 기획 등 필요
+ 추가 검토 항목 - 여러 세션의 대화를 기억하고 이어나가기
+ 추가 검토 항목 - 여러 세션의 대화 기록을 바탕으로 응답
Speaker Diarization 라이브러리 검토
검토 진행 중 음성 데이터에 여러 화자가 들어갈 수 있다는 기획이 확정되어 Speaker Diarization(화자 분리) 검토를 추가하여 진행했다. SpeechBrain, Nvdia Nemo, simple-diarizer를 비교했다.
| 항목 | SpeechBrain | NVIDIA NeMo | simple-diarizer |
| 기반 기술 | PyTorch | PyTorch + NVIDIA Riva | NumPy |
| 설치 난이도 | 중간 (pip 설치 가능, 의존성 있음) | 높음 (Docker 또는 Conda 환경 필요) | 낮음 (의존성 최소) |
| 성능 (정확도) | 중상 | 상 (고성능 GPU 기반) | 중하 |
| 실시간 지원 여부 | X (오프라인 전용) | O (오프라인/스트리밍 모두 지원) | X |
| 화자 수 자동 감지 | O | O | X (고정 필요) |
| 통합 가능성 (STT/LLM) | GPT 파이프라인과 연계 용이 | ASR 포함 end-to-end 파이프라인 제공 | 후처리 전용, 단순 구조 |
| 추론 속도 | 느림 (CPU 기준) | 빠름 (GPU 필수) | 빠름 (경량 구조) |
| 활용 추천 시나리오 | 일반 프로젝트, 오디오 분석 | 실시간 다중 화자 처리, 엔터프라이즈 | 학습 목적, 구조 실험 |
gpt 추천은 simple-diarizer 였는데, 라이선스와 정확도를 고려했을때, SpeechBrain이 적절해보였다.
- 라이브러리: SpeechBrain
+ 기획 고려 사항 - 화자 수를 입력 받기 vs 화자 수를 clustering하여 추정 vs 화자 수 입력을 참고하여 clustering
+ 추가 검토 항목 - SpeechBrain에서 지원하는 기능 추가 검토
whisper + speechbrain + llama 파이프라인 통합하여 테스트
STT → 화자분리 → LLM 로 이어지는 processing 플로우를 간단히 통합하여 테스트해보았다.
테스트 결과
{'start': 0.0, 'end': 11.88, 'speaker': 'Speaker_0', 'text': '1-3 세계속의 한국인 대화'}
{'start': 11.88, 'end': 18.68, 'speaker': 'Speaker_0', 'text': '어제만 해도 당장 포기할 것처럼 말하더니 어떻게 된 거예요?'}
{'start': 18.68, 'end': 25.24, 'speaker': 'Speaker_1', 'text': '너무 힘들어서 그만두려고 하다가 다시 힘을 내기로 했어요.'}
{'start': 25.24, 'end': 28.04, 'speaker': 'Speaker_0', 'text': '잘 생각했어요.'}
{'start': 28.36, 'end': 33.76, 'speaker': 'Speaker_1', 'text': '그런데 어떻게 마음을 바꿨어요?'}
{'start': 33.76, 'end': 37.04, 'speaker': 'Speaker_1', 'text': '어제 생각을 많이 했어요.'}
{'start': 37.04, 'end': 46.72, 'speaker': 'Speaker_1', 'text': '그러다가 포기하고 싶은 마지막 순간을 이겨내야 한다는 김현아 선수의 말이 떠올랐거든요.'}
{'start': 46.72, 'end': 54.6, 'speaker': 'Speaker_0', 'text': '맞아요. 도중에 포기하는 건 안 하는 것만 못한 것 같아요.'}
{'start': 54.6, 'end': 60.0, 'speaker': 'Speaker_1', 'text': '네. 제가 잘못 생각했던 것 같아요.'}
{'start': 60.0, 'end': 63.96, 'speaker': 'Speaker_0', 'text': '지영 씨가 힘든 거 알아요.'}
{'start': 63.96, 'end': 67.56, 'speaker': 'Speaker_0', 'text': '조금만 더 힘을 내요.'}
{'start': 67.56, 'end': 80.2, 'speaker': 'Speaker_0', 'text': '김현아 선수처럼 힘든 순간에도 포기하지 않고 끝까지 노력해야 자신의 꿈을 이루어낼 수 있
는 거니까요.'}
{'start': 80.2, 'end': 82.56, 'speaker': 'Speaker_1', 'text': '네, 알았어요.'}
{'start': 82.56, 'end': 86.16, 'speaker': 'Speaker_1', 'text': '민호 씨도 많이 도와주세요.'}
{'start': 89.76, 'end': 96.56, 'speaker': 'Speaker_0', 'text': '어제만 해도 당장 포기할 것처럼 말하더니 어떻게 된 거예요?'}
{'start': 96.56, 'end': 103.12, 'speaker': 'Speaker_1', 'text': '너무 힘들어서 그만두려고 하다가 다시 힘을 내기로 했어요.'}
{'start': 103.12, 'end': 105.72, 'speaker': 'Speaker_1', 'text': '잘 생각했어요.'}
{'start': 105.72, 'end': 111.12, 'speaker': 'Speaker_0', 'text': '그런데 어떻게 마음을 바꿨어요?'}
{'start': 111.12, 'end': 114.44, 'speaker': 'Speaker_1', 'text': '어제 생각을 많이 했어요.'}
{'start': 114.44, 'end': 124.08, 'speaker': 'Speaker_1', 'text': '그러다가 포기하고 싶은 마지막 순간을 이겨내야 한다는 김현아 선수의 말이 떠올랐거든요
.'}
{'start': 124.08, 'end': 131.96, 'speaker': 'Speaker_0', 'text': '맞아요. 도중에 포기하는 건 안 하는 것만 못한 것 같아요.'}
{'start': 131.96, 'end': 137.4, 'speaker': 'Speaker_1', 'text': '네. 제가 잘못 생각했던 것 같아요.'}
{'start': 137.4, 'end': 141.36, 'speaker': 'Speaker_0', 'text': '지영 씨가 힘든 거 알아요.'}
{'start': 141.36, 'end': 144.96, 'speaker': 'Speaker_0', 'text': '조금만 더 힘을 내요.'}
{'start': 144.96, 'end': 157.6, 'speaker': 'Speaker_0', 'text': '김현아 선수처럼 힘든 순간에도 포기하지 않고 끝까지 노력해야 자신의 꿈을 이루어낼 수
있는 거니까요.'}
{'start': 157.6, 'end': 164.24, 'speaker': 'Speaker_1', 'text': '네, 알았어요. 민호 씨도 많이 도와주세요.'}
Llama3의 답변: {
"키워드": [
"포기",
"힘들음",
"마인드 바꾸기"
],
"분위기": [
"고민",
"마인드 바꾸기",
"동력"
]
}'DevLog' 카테고리의 다른 글
| procedural 방식의 패턴 생성(1) (1) | 2025.06.06 |
|---|---|
| [캡스톤] 서버 설계 (0) | 2025.05.17 |
| [개발노트] 둥동 제작기 - 둥지동지 다시 기획하기 (0) | 2025.02.11 |
| [인터뷰] Decision Maker (0) | 2025.01.09 |
| [개발노트] 둥동제작기 - 둥지동지의 시작 (0) | 2025.01.07 |