Transformers.js에서 Cross-Origin Storage API 실험하기
Transformers.js에서 Cross-Origin Storage API 실험하기
Cross‑Origin Storage (COS) API를 사용하면 웹 앱이 URL 대신 암호화 해시를 사용하여 대용량 파일을 저장하고 검색할 수 있으며, 브라우저의 origin‑partitioned 캐시 차단 없이 오리진 간에 캐시된 리소스를 공유할 수 있습니다. Transformers.js에서 실험적 플래그를 활성화하면 개발자는 매 사이트마다 동일한 모델 가중치와 Wasm 런타임을 다시 다운로드할 필요가 없어 대역폭과 저장 공간을 절약할 수 있습니다.
Transformers.js의 캐시 격리 문제
브라우저는 타이밍 공격을 방지하기 위해 HTTP 캐시를 오리진별로 격리하므로, 서로 다른 사이트에서 가져온 동일한 리소스는 별도로 저장됩니다. Transformers.js 데모에서 https://googlechrome.github.io의 ASR 데모를 방문하면 Whisper 모델(177 MB)과 ONNX Runtime Wasm 파일(4,733 kB)이 캐시됩니다. https://rawcdn.rawgit.net과 같은 다른 오리진에서 동일한 데모를 로드하면, 바이트가 동일하더라도 브라우저는 해당 리소스를 다시 다운로드하고 캐시해야 합니다.
Cross‑Origin Storage API가 이를 해결하는 방법
COS는 URL 대신 해시(예: SHA‑256)로 파일을 식별하는 navigator.crossOriginStorage를 도입합니다. 사이트가 해시로 파일을 요청할 때, API는 해당 해시가 저장소에 이미 존재하는 경우 FileSystemFileHandle을 반환합니다. 그렇지 않으면 네트워크로 넘어가 파일을 다운로드하고 향후 사용을 위해 COS에 저장합니다. 키가 해시이기 때문에, 이전에 동일한 바이트를 저장한 적이 있는 모든 오리진이 캐시 히트(cache hit)를 얻어 중복 다운로드를 제거할 수 있습니다.
Transformers.js에 COS 통합하기
Transformers.js는 env.experimental_useCrossOriginStorage 플래그가 true로 설정되었을 때 COS를 사용하는 옵트인(opt-in) 백엔드를 제공합니다. 라이브러리는 Hugging Face Hub에 저장된 원본 포인터로부터 각 Xet‑tracked 모델 파일(예: ONNX 가중치 파일)의 SHA‑256 해시를 계산하고 해당 해시를 navigator.crossOriginStorage.requestFileHandle에 전달합니다. 파일이 COS에 존재하면 즉시 읽어오고, 존재하지 않으면 다운로드하여 다음 호출자를 위해 저장합니다. 이 기능을 활성화하려면 첫 번째 pipeline 호출 전에 다음 한 줄만 추가하면 됩니다:
import { env, pipeline } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0"); // 👇 실험적인 Cross‑Origin Storage 캐시 백엔드를 사용하도록 설정합니다.
env.experimental_useCrossOriginStorage = true;
const asr = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en', { device: 'webgpu' });
const result = await asr('jfk.wav');
console.log(result);
가시성 및 무결성 제어
COS를 통해 파일을 저장할 때 개발자는 origins 옵션을 지정할 수 있습니다:
origins: '*'는 리소스를 전역적으로 사용할 수 있게 하여 공유 모델 가중치나 Wasm 런타임에 적합합니다.origins: ['https://write.example.com', 'https://calculate.example.com']와 같은 목록은 액세스를 해당 사이트로 제한합니다.origins를 생략하면 파일은 동일 사이트(same-site) 오리진으로 제한됩니다. 가시성은 상향 조정(예: 제한적에서 전역으로)만 가능하며 절대 하향 조정될 수 없으므로, 악의적인 사이트가 공개 리소스의 시청자 층을 축소하는 것을 방지합니다. 또한 API는 쓰기 시 제공된 데이터가 선언된 해시와 일치하는지 확인합니다. 불일치 시 오류가 발생하여 추가 코드 없이도 자동 무결성 검사를 수행합니다.
개인정보 보호 고려사항
어떤 사이트든 해시를 통해 파일을 탐색할 수 있기 때문에, COS에는 가용성 게이팅(availability gating)이 포함되어 있습니다. 브라우저는 핑거프린팅을 방지하기 위해 소수의 오리진에서만 확인된 파일의 존재를 숨길 수 있습니다. 따라서 requestFileHandle에서 발생하는 오류가 파일이 없음을 확정적으로 의미하는 것은 아닙니다. 브라우저가 확인을 보류하고 있음을 나타낼 수도 있습니다. 앱은 이 오류를 캐시 미스(cache miss)로 취급하고 네트워크로 전환해야 합니다.
직접 시도해보기
오늘 바로 실험해 보려면 Chrome 웹 스토어에서 navigator.crossOriginStorage를 위한 폴리필을 주입하는 Cross‑Origin Storage 확장 프로그램을 설치하세요. 확장이 활성화된 상태에서 COS가 활성화된 https://googlechrome.github.io/samples/transformersjs-automatic-speech-recognition/index3.html에서 ASR 데모를 열어 Whisper 모델을 로드한 다음, 다른 오리진(https://rawcdn.rawgit.net/GoogleChrome/samples/1e4f2b8c10adc394352c6ec8327bb503bac7aba1/transformersjs-automatic-speech-recognition/index3.html)에서 동일한 데모를 엽니다. COS가 없을 때 관찰되는 177MB의 재다운로드 대신, 모델이 밀리초 단위로 COS에서 제공됩니다. 확장 프로그램의 팝업에는 SHA‑256 해시로 식별된 공유 리소스와 이를 저장하고 있는 두 오리진이 표시됩니다.
참여 독려
Transformers.js 앱을 구축 중이라면 첫 번째 pipeline() 호출 전에 env.experimental_useCrossOriginStorage = true를 추가하고, COS 확장을 설치한 다음, Network 탭에서 중복 다운로드가 사라지는지 확인하세요. 옵트인하는 모든 사이트가 다른 모든 사이트 사용자의 경험을 더 빠르고 저렴하게 만듭니다. 이 옵트인은 위험이 없습니다. COS API를 사용할 수 없는 경우(확장이 없는 경우) 코드는 기본 Cache API로 전환됩니다. API에 대한 피드백은 GitHub의 Cross‑Origin Storage 저장소로 보낼 수 있으며, Chrome 팀은 현재 네이티브 구현을 검토 중입니다.