이 포맷이 푼 문제는 결코 속도만이 아니었다
딥러닝 역사의 대부분 동안 "모델 파일"은 pickle을 의미했어: 파이썬의 무엇이든 직렬화하는 포맷으로, 객체에 대한 생성 절차를 기록하고 로드 시점에 재생하는 방식으로 동작하지. 그 일반성이 정확히 그 위험이야. pickle을 로드하는 건 로직을 실행하는 거야 — 임의의, 보이지 않는, 로드당 한 번의 로직. 악의적인 체크포인트는 가정이 아니야: pickle을 로드한다는 건 언제나 그 생성 로직을 실행한다는 뜻이었고, 정교하게 만든 pickle은 로드 시점에 코드를 실행해. 최근 PyTorch(2.6+)는 weights_only=True가 기본이라 임의 실행은 막아 — 무심한 이를 돕는 보호 기본값이지, 포맷 자체가 무엇인지를 바꾸진 않아. pickle 시대의 모든 "낯선 이에게서 웨이트 받기" 워크플로우는 친근한 얼굴을 한 신뢰 불가능 코드 실행이었던 거지.
safetensors는 정반대의 판을 걸었어: 행동이 아니라 데이터를 직렬화하는 것. 파일은 각 텐서를 기술하는 작은 JSON 헤더 — 이름, dtype, shape, 바이트 오프셋 — 뒤에 원시 텐서 바이트가 따라오는 구조야. 파일 안의 그 무엇도 실행 가능하지 않아. 로드는 JSON을 파싱하고 바이트를 메모리 매핑하는 일이야. 두 결과가 즉시 따라와: 로드 시점의 코드 실행이 없다는 것(보안 성질), 그리고 텐서 하나 안 읽고도 헤더만으로 레이아웃 전체를 안다는 것(검사 가능성). 더 빠른 zero-copy 로딩은 거의 부수효과였어 — 진짜 수확은 신뢰와 판독성이었지.
헤더 읽기는 기록관의 초능력이다
헤더가 파일 앞부분의 평범한 JSON이기 때문에, 표준 라이브러리만으로 safetensors 아티팩트를 감사할 수 있어: 파일을 열고, 8바이트 리틀 엔디언 헤더 길이를 읽고, 헤더 자체를 읽으면 돼. 텐서 인벤토리(이름, dtype, shape)를 전체 읽기를 저지르기 전에 알게 되는 거야. 아카이브에는 최소 세 군데서 이게 중요해: 착지한 것이 메타데이터가 약속한 것과 일치하는지 검증할 때(dtype 포렌식, 다음 레슨들), 같은 모델이라 주장하는 두 아티팩트를 diff할 때, 그리고 README 없이 낡은 드라이브에서 꺼낸 정체불명 파일을 분류할 때.
생태계는 기본값으로 투표했어: 주요 허브와 학습 프레임워크들이 배포용 표준 직렬화로 safetensors로 옮겼고, pickle 포맷은 코드와 체크포인트가 신뢰 도메인을 공유하는 내부 용도로 남겨 뒀지. 수집 관점에서는 safetensors를 기대되는 포맷 세대로 다루고 — 낯선 업로더의 pickle 포맷 아티팩트를 데이터 질문 이전의 보안 질문으로 다뤄.
헤더에 손 대보기
아래 연습은 safetensors 헤더를 표준 라이브러리 파이썬 열두 줄로 읽어 — ML 프레임워크도 의존성도 없이. 이미 갖고 있는 파일과 갓 내려받은 파일에 대해 각각 돌려 봐. 그게 출력하는 인벤토리가 config 파일과 모델 카드가 약속만 할 수 있는 것들의 실측이야.