본문 바로가기

일상

파일은 멀쩡한데 "Invalid data"라고 할 때 (에러가 터진 자리와 고장 난 자리)

반응형

음성 파일을 텍스트로 바꾸는 작업을 돌리다가, 재생은 잘 되는 파일인데 프로그램은 "잘못된 데이터"라며 멈추는 일을 겪었습니다. 파일이 깨진 게 아니었는데도요. 왜 이런 메시지가 나오는지, 이런 종류의 오류를 어떻게 읽어야 하는지 정리한 글입니다.

 

1. 증상

같은 프로그램, 같은 방식인데 어떤 파일만 실패했습니다.

av.InvalidDataError: Invalid data found when processing input:
...\Temp\tmp8xdfv71i.wav

메시지만 보면 결론은 명확해 보입니다. 파일이 손상됐다.

그런데 그 파일은 플레이어에서 멀쩡히 재생됩니다. 다른 폴더에 복사해서 돌리면 또 잘 됩니다. 파일이 깨졌다는 설명으로는 앞뒤가 맞지 않습니다.

 

2. 첫 번째 단서 - 에러가 가리키는 파일이 내 파일이 아닙니다

메시지를 다시 보면 이상한 점이 있습니다. 제가 넘긴 것은 녹음 파일인데, 오류는 tmp8xdfv71i.wav 라는 처음 보는 파일을 가리키고 있습니다.

이게 핵심입니다. 이 프로그램은 음성 파일을 곧바로 읽지 않습니다.

- 1단계 : 원본을 표준 형식(16kHz 모노 wav)으로 변환

- 2단계 : 변환된 wav를 읽어서 인식

오류는 2단계에서 났습니다. 그런데 2단계가 읽으려던 파일은 원본이 아니라 1단계가 만들어낸 임시 파일입니다. 즉 1단계에서 이미 잘못됐는데 아무도 그걸 알려주지 않은 것입니다.

 

3. 진짜 원인 - 실패를 아무도 확인하지 않았습니다

변환 부분 코드는 이렇게 생겼습니다.

문제가 두 군데 있습니다.

첫째, 빈 파일이 먼저 만들어집니다. 임시 파일을 생성하는 시점에 이미 크기 0바이트짜리 wav가 디스크에 존재합니다.

둘째, 변환 명령이 실패해도 그냥 넘어갑니다. 외부 프로그램을 실행할 때 결과를 확인하지 않으면, 실패해도 예외가 발생하지 않습니다. 함수는 아무 일 없다는 듯 임시 파일 경로를 돌려줍니다.

그래서 다음 단계는 비어 있는 wav 파일을 넘겨받아 열려고 시도하고, 당연히 "잘못된 데이터"라며 실패합니다.

정작 왜 변환이 실패했는가는 이 시점에 이미 사라진 뒤입니다.

 

4. 확인하는 법

실행 결과와 산출물을 직접 찍어보면 바로 드러납니다.

종료 코드가 정상이 아니고, 만들어진 wav는 0바이트이며, 진짜 메시지는 따로 있었습니다.

Error opening input files: Invalid argument

입력 파일을 열지 못했다는 뜻입니다. 원본은 디코딩은커녕 열린 적조차 없었습니다. 제 경우 원인은 단순했습니다. 파일이 하위 폴더에 있는데 상대 경로로 넘겨서, 실행 위치 기준으로는 그 경로에 파일이 없었던 것입니다.

 

5. 고치는 법

세 겹으로 막습니다.

- 경로를 절대 경로로 바꿔 실행 위치에 의존하지 않게 합니다

- 파일 존재를 먼저 확인해서, 없으면 그 자리에서 명확한 오류를 냅니다

- 외부 명령은 실패 시 예외가 나도록 하고, 산출물 크기까지 확인합니다

셋 다 대단한 코드가 아닙니다. 다만 이게 없으면 "파일을 못 찾았다"는 사실이 "데이터가 잘못됐다"로 둔갑해서 한참 뒤에 나타납니다.

 

6. 여기서 얻은 원칙

오류가 터진 위치와 고장 난 위치는 다를 수 있습니다.

여러 단계를 거치는 처리에서는, 앞 단계의 실패가 조용히 넘어가면 뒤 단계에서 엉뚱한 얼굴로 나타납니다. 그러면 우리는 엉뚱한 곳을 고치려 듭니다. 파일이 깨졌나 싶어 다시 녹음하거나, 라이브러리를 다시 설치하거나 합니다.

그래서 이런 오류를 만나면 먼저 물어볼 것은 하나입니다.

"이 파일, 정말 내가 준 그 파일 맞나?"

경로가 낯설다면 중간 산출물이고, 그렇다면 범인은 그것을 만든 앞 단계입니다.

 

7. 같은 작업에서 겪은 다른 함정 둘

화자 라벨은 고정된 이름이 아닙니다

여러 사람의 대화를 분리해주는 기능은 보통 화자에게 A, B 같은 임시 이름을 붙입니다. 이 이름은 파일마다 새로 매겨집니다. 첫 번째 녹음의 A와 두 번째 녹음의 A가 같은 사람이라는 보장이 없습니다. 등장 순서가 바뀌면 이름도 바뀝니다.

여러 건을 모아 분석한다면 라벨을 믿지 말고 내용으로 판단해야 합니다.

전사 결과는 초안이지 정본이 아닙니다

인식 모델은 자주 쓰이는 단어 쪽으로 기웁니다. 그래서 업계 용어나 고유명사가 발음이 비슷한 일반 단어로 바뀌는 일이 흔합니다. 문맥상 어색한 단어를 만나면 대개 원래는 그 분야의 전문 용어였습니다.

그대로 옮겨 쓰면 문서 전체가 틀린 용어로 채워집니다. 자주 나오는 용어는 치환 목록을 만들어 후보정하는 편이 안전합니다.

 

8. 정리

- 오류 메시지가 가리키는 파일 경로부터 확인합니다. 낯설면 중간 산출물입니다

- 여러 단계 처리에서는 앞 단계의 조용한 실패를 먼저 의심합니다

- 외부 명령은 실패하면 실패하도록 만들고, 산출물까지 확인합니다

- 경로는 절대 경로로 넘깁니다

- 자동 인식 결과는 초안입니다. 용어는 사람이 한 번 봐야 합니다

에러 메시지는 사실을 말하지만, 그 사실이 원인은 아닐 때가 많습니다. 데이터가 잘못됐다는 말은 맞았습니다. 다만 그 데이터를 만든 것이 우리 코드였을 뿐입니다.

 

여기까지 중간 산출물이 만든 착시 오류에 대해서 작성해봤습니다. 여기까지 읽어주셔서 감사합니다!

반응형