如何真正「不花一分錢」部署一個屬於你的大模型

2023-04-23 06:00:58

前言

看了那麼多chatGPT的文章,作為一名不精通演演算法的開發,也對大模型心癢癢。但想要部署自己的大模型,且不說沒有演演算法相關的經驗了,光是大模型佔用的算力資源,手頭的個人電腦其實也很難獨立部署。就算使用演演算法壓縮後的大模型,部署在個人電腦上,還要忍受極端緩慢的計算速度以及與chatGPT相差甚遠的模型效果。

有什麼辦法能夠部署屬於我們自己的大模型呢?其實很簡單,我們將目標拆解一下:

  • 有程式設計基礎:作為一個合格的程式設計師,這應該是必備素質。
  • 有足夠的算力資源:專業GPU自己買不起怎麼辦,阿里雲最近推出了」飛天「免費試用計劃,AI模型訓練,GPU資源免費用!
  • 要懂大模型:真的要精通大模型嗎?不需要。如果只是簡單的模型部署和使用,現在的開源模型部署已經非常簡單化,只需要掌握基礎的Python知識就可以。

隨著chatGPT的火爆,許多開源愛好者湧入AI領域,將許多與大型模型相關的工具進行進一步封裝,使得我們這些AI初學者也能夠用很少的工作量搭建一個私有大型語言模型。而且,有許多成熟的工具可供我們使用,可以幫助我們進一步使用和微調大型模型。

因此,本文是為AI初學者們(包括我自己)編寫的保姆級大型模型部署和使用指南。現在正值阿里雲免費試用計劃,我們可以不花一分錢就可以體驗部署自己的大型模型的樂趣。

下圖便是我通過阿里雲免費申請的PAI平臺資源(顯示卡是Nvidia V100),部署的清華大學chatGLM對話大模型,在網頁端和手機端都能直接體驗:

電腦端

手機端

下文圍繞如何手把手搭建一個大模型Demo展開,文章主要目錄:

  • 領取阿里雲免費使用資源
  • 建立並使用PAI平臺範例
  • 部署清華ChatGLM大模型
  • 加餐:免費額度用量查詢
  • 總結和展望

領取阿里雲免費使用資源

免費試用活動頁

https://free.aliyun.com/

只要沒有申請過PAI-DSW資源的新老使用者皆可申請5000CU的免費額度,3個月內使用。

至於5000CU能用多久,和實際申請範例的效能相關,在下面會講解。

建立並使用PAI平臺範例

官方有PAI-DSW使用教學,教你如何用領取的免費資源搭建一個Stable Diffusion來做AI畫圖,如果對SD感興趣,可以按照官方教學實踐。

https://help.aliyun.com/document_detail/615220.html

我們領取額度後,秒到賬。之後在阿里雲頁面內搜尋PAI平臺,點選立即開通,開通PAI控制檯。

開通時的頁面沒有截圖,其中有一些可選的開通項,比如NAS,比如閘道器等,可以按照自己需求選取,比如希望儲存自己的模型,那可以關聯NAS資源。我當時沒有選其他資源,僅開通了PAI,這樣沒有額外的收費。

隨後進入控制檯,建立DSW範例。

這裡選取資源,注意選擇GPU資源,並選擇支援資源包抵扣的資源。比如下圖的ecs.gn6v-c8g1.2xlarg。可以看到他們的價格裡,寫明瞭每小時消耗的CU,你可以大致計算一下,5000CU可以用多久,ecs.gn6v-c8g1.2xlarg這個型號可以跑333小時,大概連續13天。

系統可以任意選擇,本文為了部署chatGLM,選擇pytorch1.12

當然,中間你可以隨時停止機器,就不會繼續扣費。注意,這裡的機器,是隻有系統磁碟的,如果停止了機器,掛載的系統磁碟會被回收,你在上面下載的各種檔案,模型,都會回收掉。你重新啟動,是新的系統磁碟,檔案需要重新下載。(別問我怎麼知道的- -!)

建立完成後,點選開啟,就進入了互動式的Web頁面,可以開始你的模型開發之旅。

部署清華ChatGLM大模型

上面已經講完了資源的申請和範例的建立、使用,之後小夥伴們可以自行發揮,部署自己的大模型(或者任何AI相關資源)。本文後半部分介紹一下我自己折騰部署ChatGLM對話大模型的過程,給完全不瞭解大模型的小夥伴打個樣。

ChatGLM程式碼倉庫:

https://github.com/THUDM/ChatGLM-6B

大家完全可以按照官方檔案自行部署,忽略我下面的教學。也可以按照我下方的流程來操作,避免再把我踩得坑再踩一遍。

下載模型

由於模型較大(13G左右),我們最好先把模型拉到本地,再執行。

當然,如果你也可以不下載離線模型,直接在執行時拉取模型檔案。

模型檔案倉庫:

https://huggingface.co/THUDM/chatglm-6b

下載模型倉庫,需要安裝Git LFS(Large File Storage),它用來拉去Git倉庫中的大型檔案,比如這次用到的模型bin檔案。

由於我們申請的系統正好是Ubuntu,在Ubuntu下安裝Git LFS,可以使用如下命令:

sudo apt-get update

sudo apt-get install git-lfs

完成後,克隆模型倉庫:

git clone https://huggingface.co/THUDM/chatglm-6b

有可能網路波動,會導致拉取卡住,可以手動停止掉,然後進入資料夾內:

git lfs pull

這樣會拉取到上圖紅框中LFS檔案。

部署模型

完成模型下載後,我們下載模型執行程式碼:

git clone https://github.com/THUDM/ChatGLM-6B.git

進入資料夾,建立python的虛擬環境:

virtualenv -p /usr/bin/python3.8 venv

啟用Python虛擬環境:

source venv/bin/activate

如果遇到如下的報錯,需要額外安裝一下python3-dev:

Could not build wheels for pycocotools, which is required to install pyproject.toml-based projects

error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1

sudo apt-get install python3-dev

由於我們本地提前下載好了模型,我們修改一下程式碼,使用本地模型的路徑。

將使用到的程式碼中,路徑都從THUDM/chatglm-6b改為你的路徑,比如我們的模型下載在/mnt/workspace/chatglm-6b,我們將兩種部署模型的主程式碼檔案都修改一下,都修改為如下圖所示的路徑:

  • cli_demo.py: 命令列互動介面
  • web_demo.py:Web圖形互動介面

我們直接用官方提供的網頁版Demo來跑模型,啟動web_demo.py,開始模型部署,首先會將模型讀入記憶體,佔用約13個G。

完成後,記憶體會被釋放,開始佔用GPU視訊記憶體13g。

最終,部署完成會得到服務公網和本地網址。

對話效果展示

回答還是比較快的,在我們V100顯示卡的機器上,提問後1-2秒內就會開始回答問題。

以下是一個完整的對話:

我:寫一個Java單例模式程式碼

ChatGLM:以下是一個簡單的Java單例模式程式碼範例:

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

在這個範例中,Singleton 類是一個靜態類,它有一個靜態成員變數 INSTANCE,它初始化為一個單例物件。getInstance 方法返回這個單例物件的範例,可以像任何其他方法一樣使用。
單例物件通常被用於確保一個類只有一個範例,並提供全域性存取點。使用 getInstance 方法可以方便地獲取單例物件,而無需擔心多個執行緒同時存取同一個物件。
需要注意的是,在實際應用中,單例物件應該儘量避免被頻繁建立和銷燬,因為這樣會增加記憶體開銷和維護成本。因此,可以考慮使用懶載入(lazy loading)的方式來避免頻繁建立單例物件。

我:可以換一個方式實現嗎,比如懶漢式?

ChatGLM:當然可以,懶漢式單例模式的具體實現方式如下:

  1. 將 Singleton 類做成一個介面。
  2. 實現 Singleton 介面的類可以是多個,但它們都應該使用 getInstance 方法來獲取單例物件,並返回一個指向該物件的參照。
  3. 實現 Singleton 介面的類中,可以有一個內部類來負責建立單例物件。
  4. 內部類應該實現 static 關鍵字,並使用 synchronized 關鍵字實現執行緒安全。
  5. 內部類應該覆蓋 getInstance 方法,以實現懶載入。例如,可以建立一個靜態變數來儲存單例物件,並在需要時才建立該變數。
  6. 在需要使用單例物件的地方,可以呼叫內部類的方法,來獲取單例物件。
    以下是一個懶漢式單例模式的範例程式碼:
public interface Singleton {
    static Singleton INSTANCE;
}
public class ConcreteSingleton implements Singleton {
    private static Singleton INSTANCE = new ConcreteSingleton();
    @Override
    public Singleton getInstance() {
        return INSTANCE;
    }
}
public class LazySingleton implements Singleton {
    private static Singleton INSTANCE;
    private Singleton() {}
    public static Singleton getInstance() {
        synchronized (LazySingleton.class) {
            return INSTANCE;
        }
    }
}

在這個範例中,ConcreteSingleton 類使用 getInstance 方法來建立單例物件,並使用 synchronized 關鍵字實現執行緒安全。LazySingleton 類使用 synchronized 關鍵字實現懶載入,只有在需要時才建立單例物件。
需要注意的是,懶漢式單例模式仍然需要保證執行緒安全,因此在使用懶載入時,需要考慮執行緒安全問題。此外,懶漢式單例模式可能無法充分利用類的空間,因為它需要使用共用物件來實現懶載入,因此需要考慮如何提高類的效能和空間利用率。

檢視免費額度使用量

免費的5000CU額度是有三個月時效的,超過三個月會直接過期。想要做到心中有數,防止超過免費額度導致扣費。我們可以檢視免費額度的用量。在頁面右上角有「費用」標籤,選擇「資源範例管理」,點選「資源包」,能看到你的免費資源包的用量。

點選每行中的統計,可以看到是哪個範例在消耗CU。

總結

整個部署流程,我自己折騰下來也只花了半天時間,就能夠搭建好一個完整、可用的Demo。

不得不說,當AI逐漸破圈,成為一個風口時,真的是豬都會飛,普通程式設計師上手AI的難度瞬間被拉低了一個數量級。開源開發者的不斷貢獻讓各種工具和檔案變得更容易上手。每天數以萬計的大模型相關issue和pr,讓Github遇到了久違的繁榮。

在AI席捲全球的這一刻,作為一名程式設計師,我們無疑是對這個時代更有體感的那群人。此時此刻,非我莫屬。要充分關注AI技術的應用場景和發展趨勢,積極探索AI與其他領域的結合,為自己的職業發展和未來規劃提供更多的可能性。