CTC란? AI에서 소리와 글자의 위치를 미리 맞추지 않고 학습하는 방법
TL;DR
CTC(Connectionist Temporal Classification)는 소리의 어느 구간이 어느 글자인지 미리 표시하지 않아도 전체 입력과 정답 문자열로 학습하도록 하는 방식입니다. 시간 단계마다 문자와 blank의 확률을 내고 같은 정답을 만드는 여러 정렬 경로의 확률을 합쳐 손실을 계산합니다. 음성 인식과 손글씨 인식에 쓰이며 정답 자체가 필요 없는 비지도학습은 아닙니다.
핵심 3줄 요약
- 핵심 1
세부 위치 라벨을 줄입니다. 녹음과 정답 전사는 필요하지만 글자마다 시작·종료 시각을 붙이지 않아도 됩니다. - 핵심 2
여러 경로를 함께 평가합니다. 반복과 blank를 정리하면 같은 정답이 되는 경로들의 확률을 합칩니다. - 핵심 3
길이와 토큰 규칙이 중요합니다. 출력 시간 단계가 부족하거나 blank 번호가 어긋나면 학습 손실부터 잘못될 수 있습니다.
이 글에서 다룰 내용
- CTC의 한 문장 정의와 정렬의 뜻
- 반복 글자와 blank를 보는 쉬운 예시
- 정답 경로의 확률을 합치는 학습 원리
- blank·출력 길이·디코딩의 역할
- STT·교차 엔트로피·빔 서치와의 차이
- 음성·손글씨 인식의 활용과 점검 순서
- 데이터와 구현에서 주의할 점 및 FAQ
CTC를 한 문장으로 정의하면 무엇인가요?
CTC는 길이가 다른 입력 시퀀스와 정답 라벨 시퀀스 사이에서 가능한 순서 보존 정렬을 합산해 학습하는 출력 표현과 손실 함수입니다. 영문 이름은 Connectionist Temporal Classification입니다. 연결주의 시간 분류로 옮길 수 있으며 이 글에서는 공식 문서와 코드에 쓰인 약어 CTC로 부릅니다.
여기서 정렬은 줄을 가지런히 배치한다는 뜻이 아닙니다. 긴 소리 신호의 어느 위치를 정답의 어느 문자에 대응시킬지 정하는 작업입니다. 같은 단어도 말하는 사람과 속도에 따라 길이가 달라져 오디오와 글자를 한 칸씩 단순 비교하기 어렵습니다.
Graves 등의 원 논문은 미리 구간을 나누지 않은 입력에서 라벨 시퀀스를 직접 학습하는 방법을 제안합니다. PyTorch 문서도 가능한 입력·정답 정렬의 확률을 더해 미분 가능한 손실을 계산한다고 설명합니다. 모델은 이 손실이 줄어들도록 가중치를 조정합니다.
한 줄 정리: CTC는 정답이 무엇인지는 알지만 입력의 어느 위치에 놓이는지 모를 때 쓰는 시퀀스 학습 방식입니다.
쉬운 예시로 이해해 볼까요?
감자나라ai님이 짧은 녹음의 정답을 가나라고 적었다고 가정해 보겠습니다. 모델은 음성을 여러 시간 단계의 특징으로 바꾸고 각 단계에서 가·나·blank 같은 후보에 확률을 줍니다. 아래 예시는 학습 결과를 측정한 수치가 아니라 출력 규칙을 설명하는 예시입니다.
경로가
가 가 blank 나 나
라면 먼저 바로 이어진 같은 라벨을 하나로 합칩니다.
가 blank 나
가 된 뒤 blank를 지우면
가 나
가 남습니다. 여기서 보기 좋게 넣은 칸 사이 공백은 실제 정답의 띄어쓰기가 아닙니다.
정답이 가가일 때는 규칙이 더 분명해집니다.
가 가
는 반복을 합치면 가 하나가 되지만
가 blank 가
는 가운데 blank가 두 가를 구분하므로 최종적으로 가가가 됩니다. 실제로 연속해서 나온 같은 글자를 보존하는 데 blank가 필요합니다.
blank를 먼저 모두 지우고 나서 같은 문자를 합치면 이 구분이 사라집니다. 구현에서는 반복 병합과 blank 제거의 순서를 확인하세요. 직접 만든 후처리가 정답의 반복 글자까지 지우는 오류는 모델을 더 학습한다고 해결되지 않습니다.
쉬운 예시: CTC는 긴 소리 위에 정답 글자를 놓을 수 있는 여러 배치를 인정합니다. 글자의 순서는 유지하되 각 글자가 차지하는 위치와 길이는 하나로 고정하지 않습니다.
왜 AI에서 CTC가 중요한가요?
프레임별 라벨 없이 시퀀스를 학습합니다
음성 파일과 전사문은 있어도 모든 문자에 시간 경계를 붙인 자료는 없을 수 있습니다. CTC는 전체 정답 문자열을 사용하므로 세부 정렬 주석의 부담을 줄입니다. 녹음과 전사문이 서로 맞아야 한다는 조건까지 없어지는 것은 아닙니다.
말하기 속도와 입력 길이 차이를 다룹니다
같은 문장을 느리게 읽으면 모델이 처리하는 시간 단계가 늘어납니다. CTC는 반복 라벨과 blank를 포함하는 경로를 같은 문자열로 묶어 이런 차이를 다룹니다. 길이가 다르다는 이유만으로 정답 문자를 입력 프레임 수만큼 억지로 늘릴 필요가 없습니다.
학습 방식과 모델 구조를 구분하게 합니다
CTC는 특정 신경망 제품이나 한 종류의 층 이름이 아닙니다. TensorFlow 문서는 CTC가 출력과 점수 계산에 관한 방식이며 바탕 신경망 구조와는 독립적이라고 설명합니다. 모델 설명에서 CTC를 보면 어떤 출력 규칙과 학습 목표를 썼는지부터 살펴보면 됩니다.
CTC는 어떤 순서로 작동하나요?
1. 입력을 시간 단계별 점수로 바꿉니다
음성 인코더는 입력을 특징 시퀀스로 바꾸고 각 단계마다 문자나 토큰 후보의 점수를 냅니다. 후보 집합에는 일반 라벨 외에 blank가 들어갑니다. 시간 단계 수는 원본 오디오 샘플 수와 같지 않을 수 있으므로 특징 추출 뒤의 실제 길이를 사용합니다.
2. 정답으로 바뀌는 경로를 모읍니다
모든 경로를 정답으로 인정하지는 않습니다. 반복 병합과 blank 제거를 적용한 결과가 주어진 정답과 정확히 같은 경로만 포함합니다. 가나를 학습한다면 나가가 되는 경로는 제외합니다. 원래 정답의 순서를 뒤집는 정렬은 허용되지 않습니다.
3. 경로 확률을 합쳐 손실을 계산합니다
표준 CTC는 입력이 주어졌을 때 경로의 시간 단계별 확률을 곱하고 같은 정답에 해당하는 경로들의 확률을 더합니다. 학습은 정답의 합산 확률에 음의 로그를 취한 손실을 줄이는 방향으로 진행됩니다. 가장 점수가 높은 경로 하나만 정답으로 골라 학습하는 방식과는 다릅니다.
경로를 전부 나열하면 조합이 빠르게 늘어납니다. 원 논문은 앞뒤 구간의 중간 계산을 재사용하는 동적 계획법인 전방-후방 알고리즘으로 이를 계산합니다. 개발자가 모든 정렬을 직접 만드는 대신 프레임워크의 CTC 손실 함수를 사용하는 이유입니다.
4. 추론에서는 문자열을 디코딩합니다
학습이 끝난 뒤에는 출력 점수에서 실제 문자열을 골라야 합니다. 간단한 그리디 방식은 단계별 최고 확률 라벨을 택하고 CTC 병합 규칙을 적용합니다. 다만 최고 확률 경로 하나가 여러 경로의 확률을 합친 최고 확률 문자열과 항상 일치하지는 않습니다.
blank와 출력 길이는 무엇을 뜻하나요?
blank는 띄어쓰기나 무음을 뜻하지 않습니다
blank는 해당 시간 단계에서 새 라벨을 내보내지 않는 출력 기호입니다. 문장에 실제로 들어가는 띄어쓰기와 구분해야 하며 오디오에 아무 소리도 없다는 판정으로 해석해서도 안 됩니다. 소리가 이어지는 구간에도 blank가 나타날 수 있습니다.
정답보다 짧은 출력으로는 정렬할 수 없습니다
정답 라벨 수가 출력 시간 단계 수보다 많으면 유효한 CTC 경로를 만들 수 없습니다. 연속한 같은 라벨이 있으면 이를 구분할 blank 자리도 필요합니다. 가가처럼 같은 라벨 두 개를 출력하려면 최소한
가 blank 가
에 해당하는 시간 단계가 있어야 합니다.
원본 녹음이 길어도 인코더가 시간 축을 너무 많이 줄이면 문제가 생깁니다. 길이 검사는 원본 파일의 초 단위 길이만 보지 말고 CTC에 실제 전달되는 점수 배열과 정답 토큰 길이를 비교합니다. 글자 수와 토크나이저가 만든 라벨 수 역시 다를 수 있습니다.
입력값의 종류는 함수마다 다릅니다
PyTorch의
torch.nn.CTCLoss
는 로그 확률을 받습니다. 문서는
log_softmax
로 얻은 값을 예로 듭니다. 반면 TensorFlow의
tf.nn.ctc_loss
는 로짓을 받고 내부에서 소프트맥스를 수행합니다. 같은 CTC라는 이름만 보고 점수 배열을 그대로 옮기면 안 됩니다.
배치와 시간 축의 위치도 확인합니다. PyTorch의 일반적인 배치 입력은
(T, N, C)
이며 C에는 blank도 포함됩니다. TensorFlow는
logits_time_major
설정으로 시간 축 위치를 정합니다. 길이 배열은 패딩을 제외한 각 사례의 유효 구간을 가리켜야 합니다.
CTC와 헷갈리는 용어는 무엇이 다른가요?
STT와 OCR은 작업 이름입니다
STT는 음성을 텍스트로 바꾸는 작업이고 OCR은 이미지의 문자를 읽는 작업입니다. CTC는 이런 시퀀스 인식을 학습하는 데 사용할 수 있는 한 가지 방식입니다. 모든 음성 인식이나 문자 인식 시스템이 CTC를 쓰는 것은 아닙니다.
프레임별 교차 엔트로피와는 정답 대응이 다릅니다
프레임별 분류는 각 시간 단계의 정답 라벨이 주어졌다고 보고 점수를 비교합니다. CTC는 전체 정답 시퀀스를 만드는 여러 대응을 함께 계산합니다. 전사문만 있는 자료에 프레임별 정답이 있는 것처럼 임의 라벨을 반복해서 붙이는 것은 CTC 학습과 다릅니다.
빔 서치는 출력을 고르는 탐색 방법입니다
CTC는 출력 표현과 학습 손실을 정의하고 빔 서치는 추론 때 유망한 문자열 후보를 비교하는 데 쓰입니다. CTC 모델에도 그리디 디코딩이나 CTC용 빔 서치를 적용할 수 있습니다. 자세한 후보 탐색 개념은 빔 서치 용어 설명과 함께 보면 구분하기 쉽습니다.
강제 정렬은 주어진 전사의 위치를 찾습니다
강제 정렬은 이미 주어진 전사문을 입력의 시간 위치에 맞추는 작업입니다. CTC 점수와 정답 전사를 이용하는 정렬 방식도 만들 수 있지만 CTC 손실로 학습했다는 사실만으로 정확한 단어별 시작·종료 시각이 보장되지는 않습니다. 텍스트 정확도와 시간 경계 정확도는 따로 점검합니다.
비교 정리: STT·OCR은 인식 작업, CTC는 정렬을 합산하는 학습 방식, 빔 서치는 출력 후보 탐색, 강제 정렬은 주어진 전사의 위치 추정입니다.
실전에서는 어디에 쓰이나요?
음성 인식 모델을 학습하거나 미세 조정합니다
Hugging Face는
Wav2Vec2ForCTC
와 CTC 토크나이저를 문서화합니다. 음성에서 나온 점수를 CTC 규칙에 맞춰 문자로 바꾸는 실제 모델 사례입니다. 모델을 가져올 때는 출력 라벨 사전과 토크나이저가 같은 체크포인트에 맞는지도 확인합니다.
손글씨 같은 순서 있는 입력을 읽습니다
TensorFlow 문서는 온라인 손글씨 인식을 CTC 활용 예로 듭니다. 입력의 움직임이나 특징 시퀀스와 정답 문자 사이의 세부 위치를 모르는 상황에 적용합니다. 복잡한 문서의 표 구조나 읽는 순서까지 CTC 하나가 자동으로 해결한다고 확대해석하지는 않습니다.
인식 모델의 오류 원인을 나눠 봅니다
같은 모델에서도 토큰 사전, 반복 병합, blank 처리, 디코더 설정 때문에 최종 문자열이 달라질 수 있습니다. 출력이 비거나 같은 글자가 사라질 때는 학습 실패로 단정하기 전에 각 단계의 결과를 따로 저장해 비교하면 원인을 좁히기 쉽습니다.
CTC를 적용할 때 어떤 순서로 확인하나요?
먼저 입력 한 건과 정답 문자열 한 건을 직접 대조합니다. 잘린 녹음에 전체 전사문이 붙었거나 녹음 순서와 라벨 순서가 바뀌지 않았는지 봅니다. 정렬 위치를 몰라도 된다는 조건은 자료 쌍이 틀려도 된다는 허용이 아닙니다.
다음으로 라벨 사전, blank 번호, 패딩 규칙과 실제 길이를 기록합니다. 일반 정답 라벨에 blank를 끼워 넣지 않습니다. 설명용 예시의 blank는 가능한 출력 경로를 보여 주기 위한 것이며 사람이 작성하는 원래 정답 문자열의 일부가 아닙니다.
작은 배치에서 손실이 유한한지와 디코딩 결과를 확인한 뒤 학습 범위를 넓힙니다. 반복 글자, 짧은 입력, 긴 정답, 패딩이 많은 입력을 별도 사례로 둡니다. 이런 경계 사례를 먼저 확인하면 큰 학습 작업에서 같은 형식 오류를 반복하는 일을 줄입니다.
마지막으로 검증 데이터에서 전사 오류를 평가합니다. CTC 손실과 문자·단어 오류 지표를 함께 기록하고 디코더나 언어 모델을 바꿨다면 그 조건도 남깁니다. 손실의 감소와 실제 결과 문자열의 개선이 항상 같은 속도로 움직이지는 않습니다.
사용할 때 무엇을 주의해야 하나요?
첫째, 출력 순서 제약을 확인합니다. 표준 CTC는 입력을 따라 순서를 유지하는 정렬을 전제로 합니다. 입력과 출력의 순서를 크게 뒤집어야 하는 작업까지 단순히 길이만 다르다는 이유로 같은 방식에 넣지 않습니다.
둘째, 확률 모델의 가정과 인코더의 문맥 처리를 구분합니다. 표준 CTC의 경로 확률은 입력이 주어졌을 때 시간 단계별 확률을 곱하는 형태입니다. 그렇다고 인코더가 이웃 소리나 문맥을 전혀 보지 않는다는 뜻은 아닙니다. 외부 언어 모델을 붙이면 최종 후보 선택도 달라집니다.
셋째, 무한 손실을 가리는 설정만으로 문제를 끝내지 않습니다. PyTorch의
zero_infinity=True
는 무한 손실과 관련 기울기를 0으로 만듭니다. 정렬 불가능한 입력이 정상 학습 데이터로 바뀌는 것은 아니므로 길이·라벨 오류가 얼마나 발생했는지 따로 확인합니다.
넷째, 손실 평균 방식을 맞춥니다. PyTorch의 기본 평균은 사례별 손실을 정답 길이로 나눈 뒤 배치 평균을 냅니다. TensorFlow 함수는 사례별 음의 로그 확률을 반환합니다. 별도 집계 없이 두 로그의 숫자만 비교하면 모델 품질 차이로 오해할 수 있습니다.
주의: CTC는 정렬 주석을 줄이는 학습 방식입니다. 전사문 오류, 데이터 누수, 개인정보 문제나 부정확한 타임스탬프까지 해결하는 품질 보증은 아닙니다.
자주 묻는 질문
Q1. CTC는 정답 없이 학습하는 방법인가요?
아닙니다. 일반적인 CTC 학습에는 입력과 그에 맞는 정답 라벨 시퀀스가 필요합니다. 생략하는 것은 각 프레임과 문자의 세부 대응 주석입니다. 음성 자기지도 사전 학습과 CTC를 이용한 전사 학습도 구분합니다.
Q2. blank는 문장의 공백 문자와 같은가요?
다릅니다. blank는 출력 경로를 정리할 때 제거하는 특별 기호입니다. 문장 안의 띄어쓰기를 보존하려면 사전과 토크나이저에서 정한 별도 표현을 사용합니다. blank를 공백 문자로 바꿔 출력하지 않습니다.
Q3. 연속한 같은 글자는 모두 하나로 합쳐지나요?
출력 경로에서 바로 이웃한 같은 라벨은 합쳐집니다. 그러나 사이에 blank가 있으면 서로 다른 출력으로 남습니다. 그래서 반복 병합을 먼저 한 뒤 blank를 제거하는 순서가 중요합니다.
Q4. CTC 모델에는 빔 서치가 꼭 필요한가요?
필수는 아닙니다. 단계별 최고 확률 라벨을 고르는 그리디 디코딩으로도 결과를 얻습니다. 더 많은 후보를 비교할지는 검증 데이터의 전사 오류와 지연 시간을 함께 보고 결정합니다. 빔 폭을 늘렸다는 사실만으로 품질이 보장되지는 않습니다.
Q5. CTC를 쓰면 실시간 인식과 정확한 자막 시각이 보장되나요?
보장되지 않습니다. 실시간 처리는 인코더가 미래 입력을 얼마나 보는지와 청크 처리 방식에 달려 있습니다. 자막 시각은 별도 정렬·후처리와 경계 검증이 필요합니다. CTC라는 학습 목표만으로 제품의 동작 조건을 판단하지 않습니다.
출처
마무리
CTC는 긴 입력과 짧은 정답 사이의 위치를 하나로 미리 정하지 않고 같은 정답을 만드는 여러 경로의 확률을 합쳐 학습합니다. blank와 반복 병합은 그 경로를 실제 문자열로 바꾸는 핵심 규칙입니다.
처음 접한다면 정답 시퀀스는 필요하다는 점, blank는 띄어쓰기와 다르다는 점, 손실 계산과 디코딩은 별개라는 점을 기억하면 됩니다. 실제 모델에서는 출력 길이·토큰 사전·입력 점수의 종류부터 확인하세요. CTC를 이해하면 음성·문자 인식 문서에서 학습 오류와 후처리 오류를 나눠 읽기 쉬워집니다.
