แจ้งให้ผู้ใช้ทราบเกี่ยวกับการดาวน์โหลดโมเดล

เผยแพร่: 1 ตุลาคม 2025

ก่อนที่จะใช้ API ของ AI ในตัว ได้ จะต้องดาวน์โหลดโมเดลพื้นฐานและการปรับแต่ง (เช่น การปรับแต่งแบบละเอียด) จากเครือข่าย แยกข้อมูลที่บีบอัด และโหลดลงในหน่วยความจำในที่สุด คู่มือนี้จะบันทึกแนวทางปฏิบัติแนะนำบางส่วนสำหรับการปรับปรุงประสบการณ์ของผู้ใช้ขณะรอการดาวน์โหลดนี้

ตรวจสอบและแชร์ความคืบหน้าในการดาวน์โหลด

API ของ AI ในตัวทุกรายการมีฟังก์ชัน create() เพื่อเริ่มเซสชัน ฟังก์ชัน create() มีตัวเลือก monitor เพื่อให้คุณเข้าถึงความคืบหน้าในการดาวน์โหลด เพื่อแชร์กับผู้ใช้ได้

แม้ว่า API ของ AI ในตัวจะสร้างขึ้นสำหรับ AI ฝั่งไคลเอ็นต์ ซึ่งประมวลผลข้อมูล ในเบราว์เซอร์และในอุปกรณ์ของผู้ใช้ แต่แอปพลิเคชันบางอย่างก็อนุญาตให้ประมวลผลข้อมูลในเซิร์ฟเวอร์ได้ วิธีที่คุณระบุผู้ใช้ในการดาวน์โหลดโมเดล ขึ้นอยู่กับคำถามที่ว่าการประมวลผลข้อมูลต้องเรียกใช้ในเครื่องเท่านั้นหรือไม่ หากเป็นจริง แสดงว่าแอปพลิเคชันของคุณอยู่ฝั่งไคลเอ็นต์เท่านั้น หากไม่ได้ คุณสามารถใช้การติดตั้งใช้งานแบบไฮบริดในแอปพลิเคชันได้

ฝั่งไคลเอ็นต์เท่านั้น

ในบางกรณี คุณจะต้องประมวลผลข้อมูลฝั่งไคลเอ็นต์ ตัวอย่างเช่น แอปพลิเคชันด้านการดูแลสุขภาพที่อนุญาตให้ผู้ป่วยถามคำถามเกี่ยวกับ ข้อมูลส่วนบุคคลของตนเองอาจต้องการให้ข้อมูลดังกล่าวเป็นข้อมูลส่วนตัวใน อุปกรณ์ของผู้ใช้ ผู้ใช้ต้องรอจนกว่าจะดาวน์โหลดโมเดลและการปรับแต่งทั้งหมดเสร็จและพร้อมใช้งานก่อนจึงจะใช้ฟีเจอร์การประมวลผลข้อมูลได้

ในกรณีนี้ หากโมเดลยังไม่พร้อมใช้งาน คุณควรแสดงข้อมูลความคืบหน้าในการดาวน์โหลดต่อผู้ใช้

<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 event ทำงาน หลังจากดาวน์โหลดแล้ว ให้แสดง สถานะไม่แน่นอนเพื่อส่งสัญญาณให้ผู้ใช้ทราบว่าเบราว์เซอร์กำลัง ดึงข้อมูลโมเดลและโหลดลงในหน่วยความจำ
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;
  }
});

หากผู้ใช้เข้าแอปขณะที่โมเดลกำลังดาวน์โหลดไปยังเบราว์เซอร์ อินเทอร์เฟซความคืบหน้าจะระบุว่าเบราว์เซอร์อยู่ตรงไหนในกระบวนการดาวน์โหลดโดยอิงตามข้อมูลที่ยังขาดหายไป

ดูการสาธิต ที่แสดงขั้นตอนการทำงานนี้ หาก API ของ AI ในตัว (ในตัวอย่างนี้คือ Prompt API) ไม่พร้อมใช้งาน จะใช้แอปไม่ได้ หากยังต้องดาวน์โหลดโมเดล AI ในตัว ตัวบ่งชี้ความคืบหน้าจะแสดงต่อผู้ใช้ คุณสามารถ ดู ซอร์สโค้ด ได้ใน GitHub

การติดตั้งใช้งานแบบผสม

หากต้องการใช้ AI ฝั่งไคลเอ็นต์ แต่สามารถส่งข้อมูลไปยังระบบคลาวด์ได้ชั่วคราว คุณสามารถตั้งค่าการติดตั้งใช้งานแบบไฮบริดได้ ซึ่งหมายความว่าผู้ใช้จะสามารถทดลองใช้ฟีเจอร์ ได้ทันที ขณะที่ดาวน์โหลดโมเดลในเครื่องไปพร้อมๆ กัน เมื่อดาวน์โหลดโมเดลแล้ว ให้เปลี่ยนไปใช้เซสชันในเครื่องแบบไดนามิก

คุณสามารถใช้การติดตั้งใช้งานฝั่งเซิร์ฟเวอร์ใดก็ได้สำหรับไฮบริด แต่ควรใช้โมเดลในตระกูลเดียวกันทั้งในระบบคลาวด์และในเครื่องเพื่อให้มั่นใจว่าคุณจะได้รับผลลัพธ์ที่มีคุณภาพเทียบเท่ากัน การเริ่มต้นใช้งาน Gemini API และเว็บแอป จะเน้นแนวทางต่างๆ สำหรับ Gemini API

ขณะที่ดาวน์โหลดโมเดลในตัว แอปจะกลับไปใช้โมเดลในระบบคลาวด์
และพร้อมใช้งาน

การสาธิต แสดงขั้นตอนการทำงานนี้ หาก AI API ในตัวไม่พร้อมใช้งาน เดโมจะกลับไปใช้ Gemini API ในระบบคลาวด์แทน หากยังต้องดาวน์โหลดโมเดลในตัว ระบบจะแสดงตัวบ่งชี้ความคืบหน้าแก่ผู้ใช้ และแอปจะใช้ Gemini API ในระบบคลาวด์จนกว่าจะดาวน์โหลดโมเดลเสร็จ ดูซอร์สโค้ดทั้งหมดใน GitHub

บทสรุป

แอปของคุณอยู่ในหมวดหมู่ใด คุณต้องการการประมวลผลฝั่งไคลเอ็นต์ 100% หรือใช้แนวทางแบบไฮบริดได้ หลังจากตอบคำถามนี้แล้ว ขั้นตอนถัดไปคือการใช้กลยุทธ์การดาวน์โหลดโมเดลที่เหมาะกับคุณมากที่สุด

โปรดตรวจสอบว่าผู้ใช้ทราบเสมอว่าตนจะใช้แอปฝั่งไคลเอ็นต์ได้เมื่อใด โดยแสดงความคืบหน้าในการดาวน์โหลดโมเดลตามที่ระบุไว้ในคู่มือนี้

โปรดทราบว่านี่ไม่ใช่แค่การทดสอบครั้งเดียว หากเบราว์เซอร์ล้างโมเดลเนื่องจากพื้นที่เก็บข้อมูลเต็มหรือเมื่อมีโมเดลเวอร์ชันใหม่ เบราว์เซอร์จะต้องดาวน์โหลดโมเดลอีกครั้ง ไม่ว่าคุณจะใช้แนวทางฝั่งไคลเอ็นต์หรือแนวทางแบบผสม คุณก็มั่นใจได้ว่าจะสร้างประสบการณ์ที่ดีที่สุดให้กับผู้ใช้ และปล่อยให้เบราว์เซอร์จัดการส่วนที่เหลือ