ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證DeepSpeech2를 PyTorch로 직접 구현하고 내 목소리 7분으로 파인튜닝해 보는 화자 적응 실습 — 내 목소리 CER 0.261→0.165, 대신 다른 화자는 0.171→0.237로 나빠지는 망각까지
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
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는 음성을 글자로 받아쓰는 음성인식 모델입니다. 그래서 여기서 말하는 "내 목소리 학습"은 내 목소리를 만들어내는 것(음성합성·보이스 클로닝)이 아니라, 내 목소리를 더 잘 알아듣게 만드는 것입니다.檢視完整 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)는 학습 목적에 좋은 구조지만 지금 기준으로는 오래된 방식입니다. 실사용 성능이 목표라면 다음을 참고하세요. (이 프로젝트에는 적용하지 않았습니다.)