사용자에게 모델 다운로드 알림

게시일: 2025년 10월 1일

내장 AI API를 사용하려면 먼저 기본 모델과 맞춤설정 (예: 미세 조정)을 네트워크에서 다운로드하고 압축된 데이터를 추출한 후 메모리에 로드해야 합니다. 이 가이드에서는 다운로드를 기다리는 동안 사용자 환경을 개선하기 위한 몇 가지 권장사항을 설명합니다.

다운로드 진행 상황 모니터링 및 공유

모든 내장 AI API에는 세션을 시작하는 create() 함수가 있습니다. create() 함수에는 monitor 옵션이 있으므로 다운로드 진행률에 액세스하여 사용자와 공유할 수 있습니다.

내장 AI API는 브라우저와 사용자 기기에서 데이터가 처리되는 클라이언트 측 AI를 위해 빌드되지만 일부 애플리케이션에서는 서버에서 데이터를 처리할 수 있습니다. 모델 다운로드 진행 상황에서 사용자를 언급하는 방식은 데이터 처리를 로컬에서만 실행해야 하는지 여부에 따라 달라집니다. 이 값이 true이면 애플리케이션이 클라이언트 측 전용입니다. 그렇지 않은 경우 애플리케이션에서 하이브리드 구현을 사용할 수 있습니다.

클라이언트 측만

일부 시나리오에서는 클라이언트 측 데이터 처리가 필요합니다. 예를 들어 환자가 개인 정보에 관해 질문할 수 있는 의료 애플리케이션은 해당 정보가 사용자의 기기에 비공개로 유지되기를 원할 수 있습니다. 사용자가 데이터 처리 기능을 사용하려면 모델과 모든 맞춤설정이 다운로드되고 준비될 때까지 기다려야 합니다.

이 경우 모델을 아직 사용할 수 없다면 다운로드 진행률 정보를 사용자에게 노출해야 합니다.

<style>
  progress[hidden] ~ label {
    display: none;
  }
</style>

<button type="button">Create LanguageModel session</button>
<progress hidden id="progress" value="0"></progress>
<label for="progress">Model download progress</label>

내장 모델이 다운로드되는 동안에는 앱을 아직 사용할 수 없습니다.

이제 이 기능을 작동시키려면 약간의 JavaScript가 필요합니다. 코드는 먼저 진행률 인터페이스를 초기 상태 (진행률 숨김 및 0)로 재설정하고 API가 지원되는지 확인한 다음 API의 사용 가능 여부를 확인합니다.

  • API가 'unavailable'입니다. 이 기기에서 애플리케이션을 클라이언트 측으로 사용할 수 없습니다. 사용자에게 기능을 사용할 수 없다고 알립니다.
  • API는 'available'입니다. API를 즉시 사용할 수 있으므로 진행 상황 UI를 표시할 필요가 없습니다.
  • API가 'downloadable' 또는 'downloading'인 경우: 다운로드가 완료되면 API를 사용할 수 있습니다. 진행률 표시기를 표시하고 downloadprogress 이벤트가 발생할 때마다 업데이트합니다. 다운로드 후에는 브라우저가 모델을 추출하여 메모리에 로드하고 있음을 사용자에게 알리기 위해 불확정 상태를 표시합니다.
const createButton = document.querySelector('.create');
const promptButton = document.querySelector('.prompt');
const progress = document.querySelector('progress');
const output = document.querySelector('output');

let sessionCreationTriggered = false;
let session = null;

const createSession = async (options = {}) => {
  if (sessionCreationTriggered) {
    return;
  }

  progress.hidden = true;
  progress.value = 0;

  try {
    if (!('LanguageModel' in self)) {
      throw new Error('LanguageModel is not supported.');
    }

    const availability = await LanguageModel.availability();
    if (availability === 'unavailable') {
      throw new Error('LanguageModel is not available.');
    }

    let modelNewlyDownloaded = false;
    if (availability !== 'available') {
      modelNewlyDownloaded = true;
      progress.hidden = false;
    }
    console.log(`LanguageModel is ${availability}.`);
    sessionCreationTriggered = true;

    const llmSession = await LanguageModel.create({
      monitor(m) {
        m.addEventListener('downloadprogress', (e) => {
          progress.value = e.loaded;
          if (modelNewlyDownloaded && e.loaded === 1) {
            // The model was newly downloaded and needs to be extracted
            // and loaded into memory, so show the undetermined state.
            progress.removeAttribute('value');
          }
        });
      },
      ...options,
    });

    sessionCreationTriggered = false;
    return llmSession;
  } catch (error) {
    throw error;
  } finally {
    progress.hidden = true;
    progress.value = 0;
  }
};

createButton.addEventListener('click', async () => {
  try {
    localSession = await createSession({
      expectedInputs: [{ type: 'text', languages: ['en'] }],
      expectedOutputs: [{ type: 'text', languages: ['en'] }],
    });
    promptButton.disabled = false;
  } catch (error) {
    output.textContent = error.message;
  }
});

promptButton.addEventListener('click', async () => {
  output.innerHTML = '';
  try {
    const stream = localSession.promptStreaming('Write me a poem');
    for await (const chunk of stream) {
      output.append(chunk);
    }
  } catch (err) {
    output.textContent = err.message;
  }
});

모델이 브라우저에 활발하게 다운로드되는 동안 사용자가 앱에 들어가면 진행률 인터페이스는 아직 누락된 데이터를 기반으로 다운로드 프로세스에서 브라우저의 위치를 나타냅니다.

이 흐름을 보여주는 데모를 살펴보세요. 기본 제공 AI API (이 예에서는 프롬프트 API)를 사용할 수 없는 경우 앱을 사용할 수 없습니다. 내장 AI 모델을 아직 다운로드해야 하는 경우 사용자에게 진행률 표시기가 표시됩니다. GitHub에서 소스 코드를 확인할 수 있습니다.

하이브리드 구현

클라이언트 측 AI를 사용하고 싶지만 일시적으로 데이터를 클라우드로 전송할 수 있는 경우 하이브리드 구현을 설정할 수 있습니다. 즉, 사용자는 로컬 모델을 병렬로 다운로드하는 동안 기능을 즉시 경험할 수 있습니다. 모델이 다운로드되면 로컬 세션으로 동적으로 전환합니다.

하이브리드에 서버 측 구현을 사용할 수 있지만, 비교 가능한 결과 품질을 얻으려면 클라우드와 로컬 모두에서 동일한 모델 패밀리를 사용하는 것이 좋습니다. Gemini API 및 웹 앱 시작하기에서는 Gemini API의 다양한 접근 방식을 강조합니다.

내장 모델이 다운로드되는 동안 앱은 클라우드 모델로 대체되며 이미 사용할 수 있습니다.

데모에서는 이 흐름이 작동하는 모습을 보여줍니다. 내장 AI API를 사용할 수 없는 경우 데모는 클라우드의 Gemini API로 대체됩니다. 내장 모델을 아직 다운로드해야 하는 경우 사용자에게 진행률 표시기가 표시되고 모델이 다운로드될 때까지 앱은 클라우드에서 Gemini API를 사용합니다. GitHub에서 전체 소스 코드를 살펴보세요.

결론

앱이 어떤 카테고리에 속하나요? 100% 클라이언트 측 처리가 필요한가요 아니면 하이브리드 접근 방식을 사용할 수 있나요? 이 질문에 답한 후 다음 단계는 나에게 가장 적합한 모델 다운로드 전략을 구현하는 것입니다.

이 가이드에 설명된 대로 모델 다운로드 진행 상황을 표시하여 사용자가 언제 앱 클라이언트를 사용할 수 있는지 항상 알 수 있도록 하세요.

이는 일회성 문제가 아닙니다. 저장소 압력으로 인해 또는 새 모델 버전을 사용할 수 있게 되면 브라우저가 모델을 삭제하므로 브라우저가 모델을 다시 다운로드해야 합니다. 클라이언트 측 접근 방식과 하이브리드 접근 방식 중 어느 쪽을 따르든 사용자에게 최상의 환경을 제공하고 나머지는 브라우저에서 처리하도록 할 수 있습니다.