白嫖一個屬於你的私有大模型

2023-09-07 15:00:14

最近國內的大模型可謂是遍地開花,你瞧瞧:

這麼火,我也想搞一個試試,於是就有了這篇文章!對,你沒看錯,就是白嫖。

畢竟人家清華都開源了,哈哈哈hoho~~

先把開源地址貼一下,老鐵們可以自行去瞧一瞧:

https://github.com/THUDM/ChatGLM-6B
https://huggingface.co/THUDM/chatglm-6b

ChatGLM-6B 是一個開源的、支援中英雙語問答的對話語言模型,基於 General Language Model (GLM) 架構,具有 62 億引數。
結合模型量化技術,使用者可以在消費級的顯示卡上進行本地部署(INT4 量化級別下最低只需 6GB 視訊記憶體)。
ChatGLM-6B 使用了和 ChatGLM 相同的技術,針對中文問答和對話進行了優化。
經過約 1T 識別符號的中英雙語訓練,輔以監督微調、反饋自助、人類反饋強化學習等技術的加持,62 億引數的 ChatGLM-6B 已經能生成相當符合人類偏好的回答。

最重要的一點,人家遵循Apache-2.0協定。

下面開幹吧!

準備機器

畢竟是要搭建可以跑起來的環境,機器肯定是必不可少的。好在阿里雲有白嫖的使用機器。

  1. 進去阿里雲免費試用活動頁面 https://free.aliyun.com/

  2. 申請試用PAI-DSW資源,點選頁面上的【立即試用】就可以了。(我因為已經試用了,所以顯示的是「已試用」)

  3. 參考試用教學建立PAI平臺範例。或者接著往下看

  4. 在阿里雲頁面搜尋PAI,點選立即開通,然後進入到PAI控制檯。

    開通的時候,有些可選的資源(比如NAS儲存等),我因為沒有,所以都沒選。

  5. 進入控制檯後,選擇建立DSW範例

建立的時候,資源選擇GPU資源,然後選擇 支援資源包抵扣的那款 ecs.gn6v-c8g1.2xlarge

如果資源組下拉框是空白的,那麼你需要在 上圖左側【工作空間詳情】選單,設定一下計算資源。

設定的按鈕在工作空間詳情頁面右邊【資源管理】,選擇public-cluster 即可

映象選擇pytorch1.12,點選建立完成,機器就白嫖好了。

下載大模型

前面範例建立完之後,點選【開啟】,會進入到機器的web控制檯(Data Science Workshop)。

在這裡,可以在Terminal裡面操作了。

  1. 先執行安裝git相關命令

    sudo apt-get update

    sudo apt-get install git-lfs

  2. 下載模型倉庫(因為模型比較大,所以下載下來再執行方便些)

    git clone [email protected]:THUDM/chatglm-6b

  3. 下載模型執行程式碼

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

部署啟動

部署前修改原始碼

因為我們已經把模型下載下來了,部署前,需要把程式碼中的模型路徑改成你自己的。

比如我們的模型下載在/mnt/workspace/chatglm-6b,我們就需要把 ChatGLM-6B 下的兩個檔案路徑都改一下:

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

啟動

進入到ChatGLM-6B目錄,執行啟動命令即可

python web_demo.py

命令執行成功,會提示。就表示啟動成功了。

Running on local URL: http://127.0.0.1:7860

To create a public link, set share=True in launch().

如果想外網存取,就還需要改一點原始碼。在web_demo.py檔案最末尾,設定share=True

修改前:demo.queue().launch(share=False, inbrowser=True)

修改後:demo.queue().launch(share=True, inbrowser=True)

改完後,儲存,再次啟動,會列印出Running on public URL:XXXX,通過這個連結即可開啟體驗。

啟動中如果遇到缺少一些module,可通過【pip install xxx】進行安裝,安裝完之後再執行啟動命令

使用效果

使用效果的話,只能說還有相當長的路需要走。

答的是有板有眼的!但是,實際上...

我把完整的程式碼貼在下面,大家可自行體驗評論:

import java.util.concurrent.Thread;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors.newSingleThreadExecutor();
import java.util.concurrent.Future;
public class TwoThreads交替列印String {
    public static void main(String[] args) {
        int numThreads = 2;
        String str = "Hello, World!";
        int index = 0;
        ExecutorService executor = Executors.newSingleThreadExecutor();
        List<Future<void>> futures = new ArrayList<>();
        for (int i = 0; i < numThreads; i++) {
            int size = str.length();
            int start = index * size + i;
            int end = start + size;
            int buffer = start * size + size;
            // 列印前一個執行緒的輸出
            futures.add(executor.submit(() -> {
                Thread thread = new Thread(new MyThread(str, buffer));
                thread.start();
            }));
            // 列印當前執行緒的輸出
            futures.add(executor.submit(() -> {
                Thread thread = new Thread(new MyThread(str, buffer));
                thread.start();
            }));
            // 等待當前執行緒完成
            thread.join();
            // 列印下一個執行緒的輸出
            futures.add(executor.submit(() -> {
                Thread thread = new Thread(new MyThread(str, buffer));
                thread.start();
            }));
            index += size;
        }
        // 列印所有執行緒的輸出
        for (Future<void> future : futures) {
            future.get();
        }
        executor.shutdown();
    }
    private static class MyThread implements Runnable {
        private final String str;
        private final int buffer;
        public MyThread(String str, int buffer) {
            this.str = str;
            this.buffer = buffer;
        }
        @Override
        public void run() {
            for (int i = 0; i < buffer; i++) {
                System.out.print(str.charAt(i) + " ");
            }
        }
    }
}