ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
DeepSpeech2를 직접 구현해 공개 한국어 데이터로 사전학습하고, 내 목소리 8분으로 파인튜닝한 결과 데모
Translation pending
EducationPythonGitHub @dev-jonghoonparkOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
DeepSpeech2를 PyTorch로 직접 구현하고 내 목소리 7분으로 파인튜닝해 보는 화자 적응 실습 — 내 목소리 CER 0.261→0.165, 대신 다른 화자는 0.171→0.237로 나빠지는 망각까지
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
DeepSpeech2(DS2)를 PyTorch로 직접 구현하고, 공개 한국어 데이터로 사전학습한 다음 내 목소리로 파인튜닝해 보는 학습용 데모. • 🔗 데모 페이지: https://dev-jonghoonpark.github.io/ds2-my-voice/ • 📦 GitHub 레포: https://github.com/dev-jonghoonpark/ds2-my-voice • 📚 시리즈: how-ai-works — 음성 인식 (Deep Speech 2) 섹션 목표는 최고 성능이 아니라 음성인식 파이프라인 전체(녹음 → 특징 추출 → CTC 학습 → 디코딩 → 평가)를 손으로 만져 보는 것입니다. 최종 결과물은 "사전학습 모델 vs 내 목소리로 파인튜닝한 모델"을 내 목소리 테스트셋에서 비교한 CER/WER 표와, 마이크로 말하면 받아쓰는 데모입니다. 결과: 내 목소리로 파인튜닝한 게 어떤 가치가 있었나 DeepSpeech2는 음성을 글자로 받아쓰는 음성인식 모델입니다. 그래서 여기서 말하는 "내 목소리 학습"은 내 목소리를 만들어내는 것(음성합성·보이스 클로닝)이 아니라, 내 목소리를 더 잘 알아듣게 만드는 것입니다.Read the full README ↗
DeepSpeech2(DS2)를 PyTorch로 직접 구현하고, 공개 한국어 데이터로 사전학습한 다음 내 목소리로 파인튜닝해 보는 학습용 데모.
목표는 최고 성능이 아니라 음성인식 파이프라인 전체(녹음 → 특징 추출 → CTC 학습 → 디코딩 → 평가)를 손으로 만져 보는 것입니다. 최종 결과물은 "사전학습 모델 vs 내 목소리로 파인튜닝한 모델"을 내 목소리 테스트셋에서 비교한 CER/WER 표와, 마이크로 말하면 받아쓰는 데모입니다.
[Zeroth-Korean 51h] ──► 사전학습 ──► base.pt ──► 파인튜닝 ──► my_voice.pt
▲
[내 녹음 20~40분] ── train/test 분리 ─────┘ (test는 학습에 사용 안 함)
DeepSpeech2는 음성을 글자로 받아쓰는 음성인식 모델입니다. 그래서 여기서 말하는 "내 목소리 학습"은 내 목소리를 만들어내는 것(음성합성·보이스 클로닝)이 아니라, 내 목소리를 더 잘 알아듣게 만드는 것입니다.
| 테스트셋 | 사전학습 모델 CER | 내 목소리로 파인튜닝 CER |
|---|---|---|
| 내 목소리 (학습에 안 쓴 19문장) | 0.261 | 0.165 (37% 개선) |
| 다른 사람 목소리 (Zeroth 457문장) | 0.171 | 0.237 (39% 악화) |
냉장고에 우유가 다 떨어졌네요 → 사전학습 맹장보의 우휴가 다 떨어젼데요 / 파인튜닝 냉장보의 우유가 다 떨어졌네요주의할 점: 파인튜닝 모델은 테스트 19문장에서 CER이 가장 낮았던 epoch을 골랐으므로 0.165는 약간 낙관적인 수치입니다(고르지 않은 마지막 epoch도 0.177). 테스트가 19문장뿐이라 문장 몇 개에 따라 수치가 크게 흔들립니다.
학습 목적으로 만든 프로젝트입니다. DeepSpeech2(2015)는 음성인식 파이프라인을 처음부터 직접 만들고 학습시켜 보려고 고른 구조이고, 성능을 위한 선택이 아닙니다. 실제로 받아쓰기를 쓰려는 목적이라면 Whisper 계열 모델을 쓰면 무난하게 잘 됩니다. 대규모 다국어 음성으로 학습되어 파인튜닝 없이도 한국어를 잘 받아쓰고, 필요하면 LoRA 같은 방법으로 내 목소리나 분야 용어에 맞출 수 있습니다.
ds2/
tokenizer.py 한글 음절 ↔ 자모(초성/중성/종성) 토큰, CTC blank
features.py 16kHz 로딩, 선형 log 스펙트로그램(20ms/10ms, 161 bin), SpecAugment
model.py DeepSpeech2: Conv2d x2 → BiGRU x5 (sequence-wise BN) → Linear
data.py JSONL 매니페스트, 패딩 collate, SortaGrad 샘플러
decode.py greedy CTC 디코딩, CER/WER
scripts/
prepare_zeroth.py 공개 데이터 다운로드 (~3GB)
record.py 문장을 보여주고 내 목소리 녹음
split_my_voice.py 녹음을 train/test로 분리
train.py 학습 / 파인튜닝 (--init, --freeze-conv, --freeze-rnn)
compare.py 체크포인트끼리 CER/WER 비교 (결과물)
transcribe.py 파일 또는 마이크 받아쓰기
prompts/ko_prompts.txt 녹음용 문장 130개
sudo apt install libportaudio2 # 마이크 녹음용 (record.py, transcribe.py --mic)
uv sync
RTX 3070(8GB) 기준으로 설정했습니다. 메모리가 부족하면 --batch-size나 --max-duration을 줄이세요.
uv run scripts/prepare_zeroth.py --out data/zeroth
uv run scripts/train.py --train data/zeroth/train.jsonl --valid data/zeroth/test.jsonl \
--epochs 30 --lr 3e-4 --out checkpoints/base
--limit 2000으로 일부만 받아 짧게 돌려 보세요.따로 준비할 오디오 파일은 없습니다. record.py가 prompts/ko_prompts.txt의 문장을 화면에 하나씩 보여주면, 그 문장을 소리 내어 읽기만 하면 자동으로 저장됩니다.
uv run scripts/record.py --prompts prompts/ko_prompts.txt --out data/my_voice
uv run scripts/split_my_voice.py --dir data/my_voice
녹음 화면은 이렇게 진행됩니다.
[3/130] 회의가 삼십 분 늦게 시작한다고 합니다
Enter=녹음, s=건너뛰기, q=종료 > ← Enter 누르고 문장 읽기
● 녹음 중... 끝나면 Enter ← 다 읽으면 Enter
길이 2.8s, 최대 음량 0.42
저장? (Enter=저장, p=들어보기, r=다시) >
p를 누르면 방금 녹음을 들어볼 수 있습니다(여러 번 가능). 잘렸거나 잡음이 크면 r로 다시 녹음하세요.⚠ 너무 작음 또는 ⚠ 클리핑 경고가 뜨면 r로 다시 녹음하세요.s는 건너뛰기, q는 종료입니다. 다시 실행하면 녹음하던 곳부터 이어집니다.python -m sounddevice로 장치 번호를 확인하고 --device 번호를 붙이세요.data/my_voice/wav/*.wav와 metadata.jsonl(파일 경로, 문장, 길이)로 저장됩니다.문장 추가하기
prompts/ko_prompts.txt에 한 줄에 한 문장씩 쓰면 됩니다. #으로 시작하는 줄은 무시됩니다.7시 → 일곱 시train/test 분리
split_my_voice.py는 녹음을 train 85% / test 15%로 나눠 train.jsonl, test.jsonl을 만듭니다. test 문장은 학습에 쓰지 않으므로 파인튜닝 전후를 공정하게 비교할 수 있습니다.
uv run scripts/train.py --init checkpoints/base/best.pt \
--train data/my_voice/train.jsonl --valid data/my_voice/test.jsonl \
--epochs 40 --lr 5e-5 --batch-size 16 --freeze-conv --out checkpoints/my_voice
epoch 0에서 파인튜닝 전 CER을 먼저 출력하므로 바로 비교할 수 있습니다.
uv run scripts/compare.py --test data/my_voice/test.jsonl \
--ckpt base=checkpoints/base/best.pt mine=checkpoints/my_voice/best.pt
uv run scripts/transcribe.py --ckpt checkpoints/my_voice/best.pt --mic
docs/는 빌드 도구 없이 그대로 배포되는 정적 사이트입니다. 테스트 문장마다 오디오를 틀고, 사전학습/파인튜닝 모델의 받아쓰기를 틀린 글자 표시와 함께 비교하며, 학습 곡선도 보여줍니다.
uv run scripts/build_demo.py # docs/data.js, docs/audio/ 생성
cd docs && python -m http.server 8000 # http://localhost:8000 에서 미리보기
build_demo.py는 학습 로그에서 학습 곡선을 읽습니다. 기본 경로는 checkpoints/base/train.log, checkpoints/my_voice.log이므로 학습할 때 2>&1 | tee checkpoints/my_voice.log처럼 로그를 남겨 두세요 (--base-log, --mine-log로 바꿀 수 있음).--zeroth-samples).index.html, app.js, style.css는 직접 수정하는 파일이고, data.js와 audio/는 스크립트가 다시 만듭니다.배포: 저장소에 docs/까지 커밋하고 push → GitHub 저장소 Settings → Pages → Build and deployment에서 Source를 Deploy from a branch, 브랜치 main, 폴더 /docs로 지정합니다.
⚠️
docs/audio/에는 내 목소리 녹음 원본이 들어갑니다. GitHub Pages는 공개 사이트입니다. 올리기 전에 녹음 내용을 확인하세요. 목소리를 빼고 싶으면--my-samples 0으로 빌드하면 수치와 곡선만 남습니다.
| 실험 | 방법 | 관찰 포인트 |
|---|---|---|
| 사전학습 없이 내 목소리만 | --init 없이 my_voice로 학습 | train loss는 떨어지는데 test CER은 안 떨어짐 = 과적합 |
| 어떤 층을 고정할까 | --freeze-conv, --freeze-rnn 2/4 | 데이터가 적을수록 많이 고정하는 게 유리한가 |
| 학습률 | --lr 1e-5 / 5e-5 / 3e-4 | 너무 크면 base가 가진 일반 지식을 잊음(catastrophic forgetting) |
| 망각 측정 | 파인튜닝 모델로 compare.py --test data/zeroth/test.jsonl | 내 목소리는 좋아지고 다른 사람 목소리는 나빠지는가 |
| 데이터 양 | 녹음 5/10/20분으로 나눠 파인튜닝 | 몇 분부터 효과가 나는가 |
| SpecAugment | --no-augment | 적은 데이터에서 증강의 효과 |
| SortaGrad | data.py에서 첫 epoch 정렬 제거 | 초기 학습 안정성 |
eval()로 두어 BatchNorm 통계가 적은 데이터에 흔들리지 않게 합니다.DS2(2015)는 학습 목적에 좋은 구조지만 지금 기준으로는 오래된 방식입니다. 실사용 성능이 목표라면 다음을 참고하세요. (이 프로젝트에는 적용하지 않았습니다.)