RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

15-PyTorch-Edge-在邊緣設(shè)備上部署AI模型的開發(fā)者之旅

jf_pmFSk4VX ? 來源:GiantPandaCV ? 2024-01-12 10:29 ? 次閱讀

對于開發(fā)者而言,我們將整個ExecuTorch技術(shù)棧分為兩個階段。首先,我們從一個PyTorch模型開始,這在大多數(shù)情況下是一個torch.in.module。然后我們從中捕獲圖形,并將其lowering并序列化為額外的torch二進(jìn)制文件。這完成了我們的提前編譯階段。然后我們將二進(jìn)制文件放入device并使用ExecuTorch運(yùn)行時來運(yùn)行。

4cfbdf54-b088-11ee-8b88-92fbcf53809c.png

提前編譯主要有三個步驟。首先是導(dǎo)出(export),將給定的模型(如NN模塊或其他可調(diào)用對象)通過PyTorch2的torch export獲取計算圖。在這個模塊內(nèi)部,我們要列出所有正在進(jìn)行的操作的列表,并且這將產(chǎn)生一個exported program,我們將在以后更詳細(xì)地介紹它。

第二步是調(diào)用to edge,它將產(chǎn)生這個edge program,這是大多數(shù)執(zhí)行器用戶運(yùn)行優(yōu)化和轉(zhuǎn)換的入口點(diǎn)。最后一步,我們將使用to_executorch來執(zhí)行,它會將其變?yōu)橐粋€擴(kuò)展名為.pt的二進(jìn)制文件。然后我們將把它傳遞給運(yùn)行時。

4d181796-b088-11ee-8b88-92fbcf53809c.png

所以更近一步,第一步是導(dǎo)出模型,在這一步中,我們將創(chuàng)建這個模型的圖形表示。這個圖形表示是一個fx圖形,你們中的一些人可能對此很熟悉,但它不包含任何Python語義,允許我們在沒有Python運(yùn)行時的環(huán)境下運(yùn)行。這個圖形只包含操作符調(diào)用。所以如果你熟悉fx圖,就沒有像調(diào)用模塊或調(diào)用方法那樣的東西。所以對我們來說,這是一個非常簡單的圖形。導(dǎo)出產(chǎn)生的結(jié)果是一個exported program,它與torch的NN模塊非常相似,

4d322532-b088-11ee-8b88-92fbcf53809c.png

之后生成的graph,我們將其稱為Aten Dialect graph。因此,通過Dialect,我們指的是此exported program的變體,其由其操作符集和一些其他graph屬性定義。所以,通過Aten,我們指的是該圖表僅包含torch.ops.aten操作符。而且,這些操作符僅為functional操作符,意味著沒有副作用或突變。這涉及到約2000個左右的操作符。一些graph屬性是graph包含元數(shù)據(jù),例如指向原始模型的原始堆棧跟蹤指針,還有g(shù)raph內(nèi)每個節(jié)點(diǎn)的輸出data類型和形狀。我們還可以通過這些特殊的高階操作符在特定輸入上表達(dá)動態(tài)性和控制流。如需了解更多信息,您可以在下午聽Torch Expert的演講。

4d4b75d2-b088-11ee-8b88-92fbcf53809c.png

對量化而言,量化實(shí)際上在導(dǎo)出的中間階段運(yùn)行,因為它需要在更高級的opset上工作,這對于訓(xùn)練等一般情況也更安全。因此,工作流程是我們首先導(dǎo)出到Pre-Autograd,此東西訓(xùn)練是安全的,然后運(yùn)行量化,然后降低到之前提到的Aten Dialect,然后傳遞到執(zhí)行器 pipeline 的其余部分。因此,這個API看起來像是準(zhǔn)備PT2E,用戶傳入一個量化器,然后轉(zhuǎn)換PT2E,然后將其傳遞給堆棧的其余部分。所以,量化器是特定于后端實(shí)現(xiàn)的東西,它告訴用戶在特定后端上可以量化什么以及如何對這些進(jìn)行量化。它還公開了方法,允許用戶表達(dá)他們想要如何量化這個后端。

4d5cf1e0-b088-11ee-8b88-92fbcf53809c.png

下一步是lower到Edge程序,這是Executorch用戶運(yùn)行他們的目標(biāo)不可知轉(zhuǎn)換的入口點(diǎn)。此時,我們正在處理這個Edge Dialect,其中只包含一組核心的aten運(yùn)算符。大約只有180個運(yùn)算符。因此,如果你是一個新的后端,正在嘗試實(shí)現(xiàn)Executorch,你只需要實(shí)現(xiàn)這180個運(yùn)算符就可以運(yùn)行大多數(shù)模型,而不是之前來自Aten類的大約2000個運(yùn)算符。

此外,這個方言還具有數(shù)據(jù)類型的專門化,這將允許executorch根據(jù)特定的dtype類型構(gòu)建內(nèi)核,以實(shí)現(xiàn)更優(yōu)化的運(yùn)行時。我們還通過將所有標(biāo)量轉(zhuǎn)換為張量來對輸入進(jìn)行歸一化,從而使這些運(yùn)算符內(nèi)核不必隱式地進(jìn)行這種歸一化。

4d715374-b088-11ee-8b88-92fbcf53809c.png

這個邊緣程序的另一個入口是backend delegation,在這里用戶可以選擇在專門的硬件或后端上優(yōu)化和處理部分或全部程序。通過這種方式,他們可以利用這些專用硬件來處理graph的某些部分。對于此,有大約三種工作流程。第一種是分割和delegation graph的部分。或者我們可以delegation整個圖。或者我們可以做兩者的組合,將這個delegation模塊組合到更top的模塊中。

4d85ba58-b088-11ee-8b88-92fbcf53809c.png

仔細(xì)看這一點(diǎn),第一步是用戶可以傳遞一個特定于后端的patitioner,它將告訴用戶哪些操作符能在特定的后端上運(yùn)行。然后,to_backend API 將根據(jù)這個分區(qū)器對圖進(jìn)行分區(qū),然后lower這些部分為一個較低層的后端模塊。然后將該模塊傳遞給運(yùn)行時,以告訴后端需要運(yùn)行的確切內(nèi)容。它包含后端的ID,告訴我們正在運(yùn)行的后端是哪個,并且包含一組處理過的片段,告訴專用硬件需要運(yùn)行的內(nèi)容。同時,它還包含用于調(diào)試目的的原始模塊。

4da9aeae-b088-11ee-8b88-92fbcf53809c.png

第二個流程是將整個graph lower到您的backend中,然后直接將其轉(zhuǎn)換為二進(jìn)制文件,然后傳遞給運(yùn)行時在專用硬件上運(yùn)行。第三個流程是我們將完全delegation的模塊組合到其他模塊中,以便在其他地方重用。

4dc23a14-b088-11ee-8b88-92fbcf53809c.png

最后,我們可以將其轉(zhuǎn)換并保存為ExecuTorch二進(jìn)制文件。因此,用戶可以開始運(yùn)行特定于后端的轉(zhuǎn)換,例如將運(yùn)算符融合到特定的自定義后端運(yùn)算符中。然后,我們將提前運(yùn)行自定義內(nèi)存規(guī)劃過程,以確定此程序需要多少內(nèi)存。為了準(zhǔn)備graph執(zhí)行此操作,我們首先將運(yùn)行一個out variant pass,其目的是把所有運(yùn)算符變成 out variant.這樣做可以使內(nèi)存規(guī)劃變得更加容易,因為對于一個典型的算子(例如add.tensor),它會在內(nèi)核中為輸出的張量分配內(nèi)存。但是如果我們想要進(jìn)行內(nèi)存規(guī)劃,我們可以使用out variant ,它期望傳入一個預(yù)分配的張量,并在內(nèi)核中將結(jié)果張量賦值給這個預(yù)分配的張量。因此,我們可以運(yùn)行內(nèi)存規(guī)劃,非常輕松地計算張量的生命周期,并提前確定這個程序需要多少內(nèi)存,這樣我們就不需要在運(yùn)行時動態(tài)地進(jìn)行內(nèi)存分配。最后,我們可以將它轉(zhuǎn)換為擴(kuò)展名為.pte的二進(jìn)制文件,并將其傳遞給運(yùn)行時。

現(xiàn)在,孟煒將告訴我們運(yùn)行時發(fā)生了什么。希望在完成所有這些步驟后,我們能夠得到一個.pte文件。我們準(zhǔn)備深入探討運(yùn)行時的過程。

到目前為止,我們假設(shè)開發(fā)人員能夠按照Angela介紹的所有步驟進(jìn)行操作。希望就像打個響指,我們就能夠獲取Executorch的二進(jìn)制文件?,F(xiàn)在我們要考慮一些需求,比如我們該如何運(yùn)行這個二進(jìn)制文件。從開發(fā)者的角度來看,他們可能會問的第一個自然問題是:它真的能在我的目標(biāo)設(shè)備上運(yùn)行嗎?其中一些可能有CPU,或者一些可能有…甚至是微控制器。我們需要確保Executorch Runtime能夠在所有這些平臺上編譯和運(yùn)行。

現(xiàn)在我們能夠在目標(biāo)設(shè)備上編譯Executorch Runtime后,開發(fā)者可能會提出一個后續(xù)問題。我的目標(biāo)設(shè)備有一個非常特殊的地方…它包含兩個內(nèi)存緩沖區(qū)。一個速度非??斓苄?,但另一個很慢但非常龐大。Executorch Runtime是否支持這種硬件配置呢?我認(rèn)為這就是提出了我們的第二個需求,我們應(yīng)該能夠支持開發(fā)者想要的定制性,支持我們的開發(fā)人員想要的所有自定義。

好了,現(xiàn)在Executorch程序能夠在目標(biāo)設(shè)備上運(yùn)行了。開發(fā)人員可能并不在意性能問題。請注意,設(shè)備上的AI處于資源受限的環(huán)境中。這意味著效率和性能至關(guān)重要。因此,我們需要確保Executorch Runtime具備高性能。因此,讓我向您介紹一些我們?yōu)闈M足這些要求而所做的工作。

4dd5388a-b088-11ee-8b88-92fbcf53809c.png

讓我們談?wù)効梢浦残浴N覀內(nèi)绾螡M足可移植性要求?目標(biāo)設(shè)備包括不同的操作系統(tǒng)、不同的體系結(jié)構(gòu),甚至不同的工具鏈。我們解決所有這些要求的方法是隱藏系統(tǒng)級細(xì)節(jié)。我們通過提供一個平臺抽象層來實(shí)現(xiàn)。這一層提供了一組統(tǒng)一的API,用于基本功能,如日志記錄、時鐘,并抽象了許多平臺特定的實(shí)現(xiàn)細(xì)節(jié)。同樣,我們還提供了數(shù)據(jù)加載器和內(nèi)存分配器。訪問Executorch runtime以與操作系統(tǒng)進(jìn)行通信。最后但并非最不重要的是,我們確保我們的Executorch runtime遵循C++11標(biāo)準(zhǔn),這是大多數(shù)工具鏈所接受的。

4deac358-b088-11ee-8b88-92fbcf53809c.png

好的,接下來讓我們談?wù)効啥ㄖ菩?。Executorch 二進(jìn)制文件是編譯和運(yùn)行時之間的唯一橋梁。從這個意義上說,為了支持可定制性,我們必須設(shè)計二進(jìn)制文件的架構(gòu)。它只存儲高級標(biāo)識符。我們只存儲運(yùn)算符名稱和內(nèi)存池ID,但對此沒有任何意見。實(shí)際上,它是在運(yùn)行時上運(yùn)行的內(nèi)核。

4e132e10-b088-11ee-8b88-92fbcf53809c.png

這樣,我們?yōu)槎ㄖ崎_啟了很多機(jī)會。讓我們談?wù)剝?nèi)核的可定制性。我想要強(qiáng)調(diào)的一件事是允許用戶帶入他們自己的內(nèi)核。我們提供了一個內(nèi)部的可移植內(nèi)核庫。但它并不旨在優(yōu)化性能。因此,我們允許用戶帶入他們自己的內(nèi)核。注冊自定義內(nèi)核的方法非常簡單,開發(fā)者只需要按照核心 aten 運(yùn)算符的命名約定。然后,他們可以使用一個構(gòu)建工具為它們的庫注冊內(nèi)核。這個庫將幫助將他們的內(nèi)核注冊到 Executorch 運(yùn)行時中。

還有一件事我想提一下,如果開發(fā)者提供了模型級操作符信息,構(gòu)建工具會智能地只注冊必要的信息,這樣我們可以縮小二進(jìn)制文件的大小。

4e28df1c-b088-11ee-8b88-92fbcf53809c.png

不同的環(huán)境對內(nèi)存有非常特殊的需求,所以我們提供了名為MemoryManager的對象,允許用戶進(jìn)行大量的自定義配置。內(nèi)存管理器由兩個內(nèi)存分配器組成。其中一個用于初始化過程,另一個用于內(nèi)核和委托執(zhí)行過程。除此之外,我們還為張量內(nèi)存分配提供了一系列內(nèi)存緩沖區(qū)。這樣就完成了定制功能。

4e47ff1e-b088-11ee-8b88-92fbcf53809c.png

現(xiàn)在讓我們稍微談?wù)勑阅芤约拔覀內(nèi)绾螡M足性能需求。我們確保我們的Executorch Torch運(yùn)行時在內(nèi)核和委托調(diào)用之間的開銷非常低。這是通過在執(zhí)行之前準(zhǔn)備輸入和輸出張量來實(shí)現(xiàn)的。而用戶只需要付出一次代價,即使他們想多次運(yùn)行該模型。我們確保ExecuteTorch運(yùn)行時的第二個原則是保持一個非常小的二進(jìn)制文件大小以及內(nèi)存占用,這是通過將復(fù)雜邏輯和動態(tài)性推移到提前編譯器中來實(shí)現(xiàn)的,并確保Executorch運(yùn)行時邏輯。

4e5906a6-b088-11ee-8b88-92fbcf53809c.png

最后但并非最不重要的是,我們還提供了一套非常方便的性能調(diào)試工具,它在這個SDK中。讓我多談一點(diǎn),我們提供了幾個非常有用的API。其中之一是捆綁程序,我們可以將示例輸入綁定到模型中。這樣就能實(shí)現(xiàn)非??焖俚膱?zhí)行。我們還提供調(diào)試和分析工具。分析器能夠?qū)⒔y(tǒng)計數(shù)據(jù)連接到運(yùn)算符上。為我們的程序確定瓶頸非常有幫助。所有這些都提供了Python API,以確保開發(fā)人員能夠輕松使用它們。我談了很多關(guān)于我們運(yùn)行時的組件,但是我們?nèi)绾螌⑺鼈冞B接在一起并確保其正常工作呢?

4e6fb05e-b088-11ee-8b88-92fbcf53809c.png

這是一個圖表。基本上,我們加載Executorch的.pte文件。然后我們進(jìn)行一些初始化,包括加載程序和加載方法。最后,我們可以執(zhí)行它。使用SDK工具來覆蓋整個流程,確保每一步都是正確的。

4e8363c4-b088-11ee-8b88-92fbcf53809c.png

那么在初始化階段,我們在做什么呢?基本上,我們?yōu)镻yTorch模型的概念創(chuàng)建了C++對象。如您所見,根抽象稱為program,類似于nn.module模塊。一個program可以有多個方法。一個方法可能具有多個操作符,即kernel對象。

4e952366-b088-11ee-8b88-92fbcf53809c.png

當(dāng)我們加載程序時,實(shí)際上我們提供了數(shù)據(jù)加載器接口以便能夠加載二進(jìn)制文件。請注意,我們對文件系統(tǒng)不做任何假設(shè),所以用戶可以自由實(shí)現(xiàn)這個接口并在目標(biāo)設(shè)備上加載程序。加載程序?qū)⑹褂迷摂?shù)據(jù)加載器進(jìn)行二進(jìn)制文件的合法性檢查。同時,用戶也可以在初始化階段提供內(nèi)存管理器。我想要強(qiáng)調(diào)的一點(diǎn)是用戶可以管理自己的內(nèi)存。

4eaf9c64-b088-11ee-8b88-92fbcf53809c.png

初始化的最后一步是調(diào)用加載方法,開發(fā)者需要提供他們想要執(zhí)行的方法名稱,還有內(nèi)存管理器。

4ec8327e-b088-11ee-8b88-92fbcf53809c.png

最后進(jìn)入到執(zhí)行的階段:這是很簡單的循環(huán)遍歷所有指令,執(zhí)行能夠通過跳轉(zhuǎn)到特定的指令來處理控制流,并且每個指令參數(shù)都是Evalue(wrap all arg types).我們可以把他 unboxex 到不同的基礎(chǔ)類型(tensor,scalar),我們還有一個內(nèi)核運(yùn)行時上下文可以處理一些事情。

4edac8ee-b088-11ee-8b88-92fbcf53809c.png

你可以查看安卓和ios的演示,github教程可用。到此結(jié)束,謝謝。







審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 二進(jìn)制
    +關(guān)注

    關(guān)注

    2

    文章

    795

    瀏覽量

    41643
  • 可穿戴設(shè)備
    +關(guān)注

    關(guān)注

    55

    文章

    3814

    瀏覽量

    167005
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    807

    瀏覽量

    13198

原文標(biāo)題:《PytorchConference2023 翻譯系列》15-PyTorch-Edge-在邊緣設(shè)備上部署AI模型的開發(fā)者之旅

文章出處:【微信號:GiantPandaCV,微信公眾號:GiantPandaCV】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    AI模型部署邊緣設(shè)備的奇妙之旅:如何實(shí)現(xiàn)手寫數(shù)字識別

    。ONNX通過定義一種標(biāo)準(zhǔn)化的模型交換格式打破了這種限制,允許模型PyTorch、TensorFlow、MXNet等流行框架之間自由轉(zhuǎn)換。這意味著
    發(fā)表于 12-06 17:20

    AI模型部署邊緣設(shè)備的奇妙之旅:目標(biāo)檢測模型

    以及邊緣計算能力的增強(qiáng),越來越多的目標(biāo)檢測應(yīng)用開始直接在靠近數(shù)據(jù)源的邊緣設(shè)備上運(yùn)行。這不僅減少了數(shù)據(jù)傳輸延遲,保護(hù)了用戶隱私,同時也減輕了云端服務(wù)器的壓力。然而,
    發(fā)表于 12-19 14:33

    EdgeBoard FZ5 邊緣AI計算盒及計算卡

    科技攜手百度,推出系列高性能及高性價比EdgeBoard 邊緣AI計算卡/計算盒,助力AI項目落地??伸`活適配海量的且不斷迭代的AI模型,并
    發(fā)表于 08-31 14:12

    介紹STM32cubeIDE上部署AI模型的系列教程

    介紹STM32cubeIDE上部署AI模型的系列教程,開發(fā)板型號STM32H747I-disco,值得一看。MCUAI原文鏈接:【嵌入式
    發(fā)表于 12-14 09:05

    Pytorch模型如何通過paddlelite部署到嵌入式設(shè)備?

    Pytorch模型如何通過paddlelite部署到嵌入式設(shè)備?
    發(fā)表于 12-23 09:38

    通過Cortex來非常方便的部署PyTorch模型

    (比如移動設(shè)備)非常有用。大多數(shù)情況下,你會使用模型服務(wù)器。今天你看到的許多 ML 應(yīng)用程序 — 從你最喜歡的流媒體服務(wù)背后的推薦引擎到在線搜索欄中的自動完成功能—都依賴于這種部署
    發(fā)表于 11-01 15:25

    嵌入式邊緣AI應(yīng)用開發(fā)指南

    、針對性能和精度目標(biāo)對模型進(jìn)行訓(xùn)練和優(yōu)化,以及學(xué)習(xí)使用在嵌入式邊緣處理器上部署模型的專用工具。從模型選擇到
    發(fā)表于 11-03 06:53

    ST MCU邊緣AI開發(fā)者云 - STM32Cube.AI

    生成針對STM32優(yōu)化的“入門”包。? STM32板上訪問全球首個邊緣AI神經(jīng)網(wǎng)絡(luò)在線基準(zhǔn)測試服務(wù)。云訪問板場具有廣泛的STM32板,定期更新,使數(shù)據(jù)科學(xué)家和開發(fā)人員能夠遠(yuǎn)程測量優(yōu)化
    發(fā)表于 02-02 09:52

    Pytorch模型轉(zhuǎn)換為DeepViewRT模型時出錯怎么解決?

    我最終可以 i.MX 8M Plus 處理器上部署 .rtm 模型。 我遵循了 本指南,我將 Pytorch 模型轉(zhuǎn)換為 ONNX
    發(fā)表于 06-09 06:42

    如何使用TensorFlow將神經(jīng)網(wǎng)絡(luò)模型部署到移動或嵌入式設(shè)備

    有很多方法可以將經(jīng)過訓(xùn)練的神經(jīng)網(wǎng)絡(luò)模型部署到移動或嵌入式設(shè)備上。不同的框架在各種平臺上支持Arm,包括TensorFlow、PyTorch、Caffe2、MxNet和CNTK,如And
    發(fā)表于 08-02 06:43

    【KV260視覺入門套件試用體驗】Vitis AI 構(gòu)建開發(fā)環(huán)境,并使用inspector檢查模型

    推斷開發(fā)平臺,它可以幫助開發(fā)者賽靈思的 FPGA 和自適應(yīng) SoC 上實(shí)現(xiàn)高效的 AI 應(yīng)用部署。它是一個強(qiáng)大而靈活的
    發(fā)表于 10-14 15:34

    NVIDIA 舉辦 Jetson Edge AI 開發(fā)者大賽,建立開放的開發(fā)者社區(qū)

    、無人機(jī)、IVA 應(yīng)用程序以及其他獨(dú)立思考的自主機(jī)器。 NVIDIA 鼓勵大學(xué)生及社會創(chuàng)客開發(fā)具有創(chuàng)新和引領(lǐng)作用的 Edge AI 相關(guān)應(yīng)用,發(fā)掘與培養(yǎng)更多的創(chuàng)新 AI 應(yīng)用與優(yōu)秀
    的頭像 發(fā)表于 11-10 11:40 ?800次閱讀
    NVIDIA 舉辦 Jetson <b class='flag-5'>Edge</b> <b class='flag-5'>AI</b> <b class='flag-5'>開發(fā)者</b>大賽,建立開放的<b class='flag-5'>開發(fā)者</b>社區(qū)

    OpenNCC上部署人臉檢測模型

    電子發(fā)燒友網(wǎng)站提供《OpenNCC上部署人臉檢測模型.zip》資料免費(fèi)下載
    發(fā)表于 06-27 10:34 ?0次下載
    <b class='flag-5'>在</b>OpenNCC<b class='flag-5'>上部署</b>人臉檢測<b class='flag-5'>模型</b>

    Arm推出GitHub平臺AI工具,簡化開發(fā)者AI應(yīng)用開發(fā)部署流程

    軟件提供了無縫的開發(fā)體驗。 GitHub Actions、原生 GitHub 運(yùn)行器和基于 Arm 平臺的 AI 框架相結(jié)合,幫助全球 2,000 萬開發(fā)者簡化 AI 應(yīng)用
    的頭像 發(fā)表于 10-31 18:51 ?1941次閱讀

    設(shè)備上利用AI Edge Torch生成式API部署自定義大語言模型

    使用 TFLite 運(yùn)行時的設(shè)備上實(shí)現(xiàn)高性能的 PyTorch 模型推理。 AI Edge Torch 生成式 API 使
    的頭像 發(fā)表于 11-14 10:23 ?416次閱讀
    <b class='flag-5'>在</b><b class='flag-5'>設(shè)備</b>上利用<b class='flag-5'>AI</b> <b class='flag-5'>Edge</b> Torch生成式API<b class='flag-5'>部署</b>自定義大語言<b class='flag-5'>模型</b>
    RM新时代网站-首页