網(wǎng)頁也能跑大模型?

banner.png

寫在最前

本故事主要介紹在網(wǎng)頁上部署模型的來龍去脈江锨,你想問的問題吃警,可能都可以在這里找到答案

在這個(gè) AI 內(nèi)容生成泛濫的時(shí)代,依然有一批人"傻傻"堅(jiān)持原創(chuàng)啄育,如果您能讀到最后酌心,還請(qǐng)點(diǎn)贊或收藏或關(guān)注支持下我唄,感謝 ( ̄︶ ̄)↗

能在網(wǎng)頁上跑模型嗎挑豌?

丹尼爾:嘿谒府,蛋兄,你這是要去哪兒遛彎呢浮毯?

蛋先生:剛吃完飯,準(zhǔn)備散下步消消食

丹尼爾:一起唄泰鸡。蛋兄债蓝,我最近對(duì) AI 有點(diǎn)著迷,突然冒出個(gè)念頭盛龄,你說咱們能不能在網(wǎng)頁上跑機(jī)器學(xué)習(xí)模型呢饰迹?

蛋先生:這個(gè)嘛芳誓,確實(shí)可以

為什么可以在網(wǎng)頁上跑模型?

丹尼爾:這我就納悶了啊鸭,一個(gè)專門看網(wǎng)頁的瀏覽器锹淌,怎么還能“兼職”跑模型呢?蛋兄赠制,快給我講講唄

蛋先生:你想啊赂摆,一顆種子能不能發(fā)芽,得看它有沒有適合生存的環(huán)境钟些。模型也一樣烟号,得有個(gè)能跑的“土壤”——runtime,還得有足夠的“陽光”和“水”——也就是算力和存儲(chǔ)

丹尼爾:哦政恍,我好像有點(diǎn)懂了汪拥。但我還是不明白,瀏覽器是怎么做到這一點(diǎn)的

蛋先生:自從瀏覽器有了 WebAssembly 之后篙耗,它的“胃口”可就大了去了迫筑!現(xiàn)在,很多用 C宗弯、C++脯燃、Rust 等編程語言寫的應(yīng)用,都能編譯成 WASM 格式罕伯,在瀏覽器里跑曲伊。這樣一來,瀏覽器就能處理更加復(fù)雜的計(jì)算任務(wù)了

丹尼爾:原來如此追他!也就是說坟募,原來用 C++ 等寫的模型 runtime,現(xiàn)在可以直接放進(jìn)瀏覽器里邑狸,成了模型的“土壤”了懈糯!

蛋先生:對(duì)頭!而且单雾,瀏覽器的 WebGL赚哗、WebGPU 這些技術(shù),還能讓你的應(yīng)用用上 GPU 資源硅堆,速度更上一層樓屿储!否則,能跑渐逃,但很慢够掠,也沒啥意義

丹尼爾:哈哈,我總結(jié)一下啊茄菊,WebAssembly 讓模型有了土壤疯潭,WebGL赊堪、WebGPU 讓算力提升成為可能!

蛋先生:不錯(cuò)不錯(cuò)竖哩,總結(jié)得挺到位哭廉!

為什么要跑在瀏覽器呢?

蛋先生:那我問你相叁,你為什么想把模型跑在瀏覽器上呢遵绰?

丹尼爾:額~,這~钝荡,就覺得挺酷的嘛街立!不過說實(shí)話,我還真沒認(rèn)真想過這個(gè)問題埠通。蛋兄赎离,你給說道說道?

蛋先生:來端辱,咱們從請(qǐng)求鏈路說起梁剔。模型部署在瀏覽器上,是不是就不用請(qǐng)求服務(wù)器了舞蔽?

1.png

丹尼爾:那是肯定的

蛋先生:對(duì)于客戶端荣病,請(qǐng)求沒有離開用戶設(shè)備,這樣是不是就可以更好地保護(hù)用戶隱私了渗柿?

丹尼爾:是哦

蛋先生:計(jì)算是在瀏覽器本地進(jìn)行的个盆,距離用戶更近,也沒有網(wǎng)絡(luò)請(qǐng)求的損耗朵栖,響應(yīng)速度通常更快颊亮,這樣是不是就可以提升用戶體驗(yàn)了?

丹尼爾:是哦

蛋先生:還有陨溅,模型已經(jīng)部署在瀏覽器了终惑,只要應(yīng)用本身支持離線訪問,那是不是就可以離線使用了门扇?

丹尼爾:是哦

蛋先生:對(duì)于服務(wù)端雹有,因?yàn)榘延?jì)算壓力分?jǐn)偝鋈チ耍遣皇蔷涂梢詼p輕服務(wù)器的計(jì)算壓力臼寄,降低運(yùn)營(yíng)成本呢霸奕?

丹尼爾:是哦

蛋先生:剩下的你自己琢磨琢磨吧

怎么跑在瀏覽器呢?

丹尼爾:好嘞吉拳,那具體要怎么實(shí)現(xiàn)呢质帅?

蛋先生:主流的機(jī)器學(xué)習(xí)框架除了訓(xùn)練模型外,還能部署和推理模型。比如大名鼎鼎的 Tensorflow 就有 tensorflow.js临梗,它可以將模型部署在瀏覽器端。不過今天我要給你說的是 onnxruntime-web

丹尼爾:onnxruntime-web稼跳?這名字聽著有點(diǎn)新鮮懊伺印!

蛋先生:onnxruntime-web汤善,可以把這個(gè)拆成 onnx什猖,onnxruntime 和 onnxruntime-web 來說

丹尼爾:您繼續(xù)

蛋先生:onnx 就是個(gè)模型格式,就像你存音樂用的 mp3 格式一樣红淡,但它存的是機(jī)器學(xué)習(xí)模型不狮;onnxruntime 呢,就是運(yùn)行這些模型的“播放器”在旱;而 onnxruntime-web摇零,則是讓這個(gè)“播放器”能在網(wǎng)頁上跑起來的神奇工具

丹尼爾:哦,那模型都有哪些格式呢桶蝎?用這個(gè) onnx 有什么優(yōu)勢(shì)呢驻仅?

蛋先生:正所謂合久必分,分久必合

丹尼爾:這是要講三國(guó)的節(jié)奏嗎

蛋先生:各個(gè)機(jī)器學(xué)習(xí)框架都有自己的模型格式登渣,在沒有 onnx 之前噪服,你得用 tf 來部署 tensorflow 的模型,用 pytorch 來部署 pytorch 的模型胜茧≌秤牛可用戶只想部署個(gè)模型而已,能不能把問題簡(jiǎn)單化呢呻顽?

2.png

丹尼爾:確實(shí)

蛋先生:于是就有了 onnx 這個(gè)開放標(biāo)準(zhǔn)雹顺。各家的模型格式都能轉(zhuǎn)換成這種標(biāo)準(zhǔn)格式,然后你就可以用一個(gè) onnxruntime 來部署和推理模型了芬位!

3.png

丹尼爾:那這個(gè) onnxruntime 是用什么實(shí)現(xiàn)的呢无拗?

蛋先生:它是用 C++ 實(shí)現(xiàn)的,在瀏覽器運(yùn)行時(shí)會(huì)被編譯成 WASM 格式昧碉。然后 onnxruntime-web 提供了 JS API 來與 WASM 進(jìn)行交互

丹尼爾:原來如此英染!那快給我看個(gè)代碼示例吧,我都迫不及待了

蛋先生:以下是一個(gè)數(shù)字圖像識(shí)別的簡(jiǎn)單例子被饿,不過接口有點(diǎn)底層哦四康,你得懂點(diǎn) tensor 之類的。希望以后有第三方庫能封裝個(gè)高級(jí)的接口狭握,比如手寫數(shù)字識(shí)別輸入是圖片闪金,輸出是數(shù)字;生成式 AI 輸入是 prompt,輸出是回答之類的哎垦。當(dāng)然你也可以自己嘗試嘗試

4.png
<!DOCTYPE html>
<html lang="en">
  <head>
    ...
    <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
    ...
  </head>
  <body>
    ...
    <canvas id="canvas" width="28" height="28" style="display: none"></canvas>

    <script>
      let imageData;

      ...

      async function runModel() {
        // 提取圖像數(shù)據(jù)并規(guī)范化為模型的輸入格式
        const input = new Float32Array(28 * 28);
        for (let i = 0; i < input.length; i++) {
          const r = imageData.data[i * 4];
          const g = imageData.data[i * 4 + 1];
          const b = imageData.data[i * 4 + 2];
          const gray = 0.299 * r + 0.587 * g + 0.114 * b; // 轉(zhuǎn)換為灰度值
          input[i] = gray / 255.0; // 規(guī)范化到 0~1
        }
        const inputTensor = new ort.Tensor("float32", input, [1, 1, 28, 28]);

        // 使用 mnist-12.onnx 模型創(chuàng)建推理會(huì)話
        const session = await ort.InferenceSession.create(
          "https://media.githubusercontent.com/media/onnx/models/refs/heads/main/validated/vision/classification/mnist/model/mnist-12.onnx"
        );

        // 推理
        const results = await session.run({ Input3: inputTensor });
        const output = results.Plus214_Output_0.data;

        // 找到最大值(概率最大)的索引囱嫩,即預(yù)測(cè)的數(shù)字
        const predictedDigit = output.indexOf(Math.max(...output));

        // 顯示結(jié)果
        document.getElementById("output").innerText = predictedDigit;
      }

      ...
    </script>
  </body>
</html>

有什么限制?

丹尼爾:除了數(shù)字識(shí)別漏设,還能玩點(diǎn)兒別的花樣不墨闲?

蛋先生:那當(dāng)然咯!語音識(shí)別郑口、圖像分類鸳碧、對(duì)象檢測(cè),甚至生成式 AI犬性,都不在話下瞻离!

丹尼爾:哇塞,連大語言模型都能搞定乒裆?

蛋先生:不過在瀏覽器上運(yùn)行有些小小的限制

丹尼爾:讓我來猜猜套利,是不是模型的大小有限制?

蛋先生:對(duì)頭

丹尼爾:具體能多大呢缸兔?

蛋先生:首先我們得加載遠(yuǎn)程模型

各大瀏覽器對(duì) ArrayBuffer 的大小都是有限制的日裙,比如 Chrome 就是2G。當(dāng)你用 fetch 去加載模型時(shí)惰蜜,需要用到 response.arrayBuffer()昂拂,如果模型超過2G,就 GG 了

還有啊抛猖,ONNX 模型是通過 protobuf 格式進(jìn)行傳輸?shù)母窈睿琾rotobuf 單個(gè)消息的大小限制也剛好是 2G

丹尼爾:所以最多只能加載2G的模型了?

蛋先生:那也不完全是财著。一次不行联四,我們可以分次嘛!我們可以將模型分成模型圖和權(quán)重撑教,權(quán)重信息作為外部數(shù)據(jù)另外加載即可朝墩。只要模型圖不超過2G,咱就可以突破這2G的限制了

丹尼爾:那豈不是可以加載超級(jí)大的模型了伟姐?

蛋先生:嘿嘿收苏,別高興得太早。模型最終是要加載到運(yùn)行時(shí)環(huán)境的愤兵,而我們的運(yùn)行時(shí)是在 WebAssembly 環(huán)境中鹿霸。根據(jù) WebAssembly 規(guī)范,Memory 對(duì)象的大小頂多4G秆乳。所以理論上4G就是天花板了

丹尼爾:哦……

蛋先生:而且啊懦鼠,當(dāng)模型太大時(shí)钻哩,對(duì)硬件的要求就更高了。這些大家伙就不推薦放在瀏覽器里折騰了

丹尼爾:明白了肛冶,那我去試一下咯

蛋先生:好的街氢,祝你好運(yùn)!

寫在最后

親們睦袖,都到這了阳仔,要不,點(diǎn)贊或收藏或關(guān)注支持下我唄 o( ̄▽ ̄)d

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扣泊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嘶摊,更是在濱河造成了極大的恐慌延蟹,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叶堆,死亡現(xiàn)場(chǎng)離奇詭異阱飘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)虱颗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門沥匈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忘渔,你說我怎么就攤上這事高帖。” “怎么了畦粮?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵散址,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我宣赔,道長(zhǎng)预麸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任儒将,我火速辦了婚禮吏祸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钩蚊。我一直安慰自己贡翘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布两疚。 她就那樣靜靜地躺著床估,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诱渤。 梳的紋絲不亂的頭發(fā)上丐巫,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼递胧。 笑死碑韵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缎脾。 我是一名探鬼主播祝闻,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼遗菠!你這毒婦竟也來了联喘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤辙纬,失蹤者是張志新(化名)和其女友劉穎豁遭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贺拣,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蓖谢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了譬涡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闪幽。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖涡匀,靈堂內(nèi)的尸體忽然破棺而出盯腌,到底是詐尸還是另有隱情,我是刑警寧澤陨瘩,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布羡铲,位于F島的核電站侨舆,受9級(jí)特大地震影響寺旺,放射性物質(zhì)發(fā)生泄漏男窟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一蒿囤、第九天 我趴在偏房一處隱蔽的房頂上張望客们。 院中可真熱鬧,春花似錦材诽、人聲如沸底挫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽建邓。三九已至,卻和暖如春睁枕,著一層夾襖步出監(jiān)牢的瞬間官边,已是汗流浹背沸手。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留注簿,地道東北人契吉。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像诡渴,于是被迫代替她去往敵國(guó)和親捐晶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 寫在最前 時(shí)光飛逝,物是人非 技術(shù)方案總是帶著時(shí)代的標(biāo)簽眼耀,曾經(jīng)前沿的技術(shù)泣棋,經(jīng)過時(shí)間的洗禮,可能已成為經(jīng)典 如果你點(diǎn)...
    蛋先生DX閱讀 156評(píng)論 0 0
  • 設(shè)計(jì)思維 原理:一種以人為本的解決問題的方法論畔塔,從人的需求出發(fā),多角度的提出解決方案鸯屿。操作:同理心思考需求定義創(chuàng)意...
    不同而大同閱讀 418評(píng)論 0 4
  • 項(xiàng)目管理無處不在 模型:展現(xiàn)優(yōu)化工作流程與任務(wù)的情境澈吨、策略或方法。 1. 情境領(lǐng)導(dǎo)模型 情境領(lǐng)導(dǎo):成員的職能(能力...
    行者百里半九十閱讀 408評(píng)論 0 0
  • 薦 語 當(dāng)所有信息在網(wǎng)上都能查到的時(shí)候寄摆,腦袋里記憶多少知識(shí)還重要嗎谅辣? 答案是,依然重要婶恼。海量的知識(shí)被存在云端桑阶,可如...
    內(nèi)鄉(xiāng)老彭友閱讀 1,405評(píng)論 0 7
  • 當(dāng)所有信息在網(wǎng)上都能查到的時(shí)候,腦袋里記憶多少知識(shí)還重要嗎勾邦? 答案是蚣录,依然重要。海量的知識(shí)被存在云端眷篇,可如果它們不...
    晨峰_02c6閱讀 802評(píng)論 0 0