Steve Comparison of LLMs

About the author

這篇文章是由我的實習生Steve Wang所撰寫

More about Steve Wang: https://renickbell.net/students/steve-wang/doku.php?id=start

Introduction

Here the author performs a comparison of different LLM AI models. The goal is to find the best LLM that can understand and reply in Traditional Chinese. A requirement is that this LLM should serve those physically and mentally handicapped or disadvantaged groups and help them understand how to apply for government welfare resources in Taiwan.This is important because most of the time, government websites often use lawyer speak. The categories under analysis will be speed of reply, reasoning ability, and clarity in traditional Chinese. Some models will be run on device and others in the cloud. The ones that will be run in the cloud include gpt4o (OpenAI) and Gemini 1.5 flash (Google). The ones run locally include Mistral and Llama3.2 will be run using Ollama on a laptop with an NVIDIA GeForce RTX 3070 Ti Laptop GPU.

Due to the fact that some models are run locally and others in the cloud, the time measurements would cause inconsistencies in measurements and thus will not be considered in comparisons made. All these tests will be run in the Dify interface. The device running Dify will be the same device running the models with Ollama. To reduce network latency, the same laptop was hooked up to wired internet which had an average of 600.44 mbps download and 51.26 mbps upload on the browser version of Speedtest.

Research Methods

The testing process was as follows. A basic Dify workflow will be created with a startpoint leading to one of the models. Process as follows:

The LLM was prompted like so:

You are a chatbot designed to help serve some physically and mentally handicapped or disadvantaged groups and help them understand how to apply for government welfare resources in Taiwan. Answer like a person from Taiwan and in traditional Chinese. Remember the person you are speaking with is most likely from Taiwan so respond accordingly.

  

here is the question from user: {question from user}


The first question prompted by the user was “我該如何申請低收入戶補助?”. The follow up question “告訴我臺灣臺北市的低收入資格”. Following that: “根據你上面提供的資料. 我在臺北市住. 在臺北市有租一個房間. 月收13,455元 我可以申請嗎?”. It was believed that these questions would test if the LLM would reply in full traditional Chinese, give a relatively good idea of the speed of the LLM, and test if the LLM has good reasoning skills. When calculating the time, only the time necessary for the LLM to produce a response was calculated. Shown in image below (circled in red). These prompts were designed in this way to simulate a generally authentic, real-life usage case, not a clinical scientific study.

Dify interface time circled

The accuracy of the responses were not judged because of possible hallucinations and the fact that the actual correct information would be provided to the system in a real world use case. However, the accuracy of answers based on the information that each LLM came up with was judged to test reasoning ability. In other words, we treated all responses produced as fact for each testing scenario. The “facts” each LLM came up with were used to judge their following responses.

Results

LLama3.2 (Meta)

llama3.2 took 9.883 s, 2.919 s, and 2.419 s respectively to answer each question. All of the responses are in traditional Chinese but there are a few glitches observed. For instance, “住住的人” that can be found in the responses of question 2 and 3. Other than that, the answers seemed to be fine, the logic and reasoning sound. Llama also sounded quite professional. This model appears to suit the goal quite well. View full response from LLama3.2 in the Full Response from LLMs section below.

Mistral (Mistral AI)

Mistral took 12.312 s, 29.308 s, and 16.970 s respectively to answer each of the questions. There is some use of Simplified Chinese. For instance, “身份” in responses one and responses two and “证明” in responses one and two. It seems that the language is accurate and the logic is quite clear. Another thing of note is, Mistral always starts responses with: “您好!” which might make the conversation feel robotic because there is not variation.

Gemini 1.5 Flash (Google)

Google Gemini 1.5 Flash took 8.516 s, 11.995 s, and 9.561 s respectively to answer each question. All responses are in traditional Chinese and the language is quite clear and accurate. The logic and reasoning is sound. It seems that Gemini can follow the conversion quite well. An interesting thing to note is that Gemini’s tone is very friendly which could help people using it feel more comfortable. However, perhaps due to this, most of its answers follow a formulaic format. Gemini would mostly start with a greeting and end with a sentence of encouragement. As a non-native Chinese speaker, the writer is unsure how this would make people in Taiwan feel. All in all, Gemini is quite a good fit for the goals.

gpt4o-mini (OpenAI)

gpt40-mini took 3.594 s, 2.580 s, and 2.488 s respectively to answer each question. There are some responses in Simplified Chinese. For instance, in the first response, gpt4o-mini uses “台灣” instead of “臺灣”. However it would seem that this is acceptable to some people living in Taiwan. Other than that, the language is clear and accurate. The logic and reasoning is sound. The writer observes that gpt4o seems to be very careful and tries to not give specific answers until there is correct information. This point makes gpt4o a good model to achieve research goals.

Discussion

From the results, only Gemini 1.5 Flash, LLama3.2, and gpt40-mini could give all the responses in traditional Chinese. Both have acceptable speeds that would not make the user feel impatient. Compared to Llama3.2, Gemini 1.5 Flash had better Chinese skills and responded without making mistakes. Gemini 1.5 Flash was also quite comforting and encouraging in its tone which might make it ideal for communicating with physically and mentally handicapped or disadvantaged groups and help them understand how to apply for government welfare resources.

Conclusion

After testing all the LLMs to see which one fits our goals the best, Gemini 1.5 Flash and gpt40-mini seems to be the best choice at the moment. To further narrow down the best LLM for the task, tests could be done on bigger models like llama3 with 70b parameters (Llama3.2 has 3b). To reduce cost and the network speed of using Gemini models from Google, testing could be done on Gemma or Gemma2 these model are both available on Ollama and are from Google.

Full Responses from LLMs

正確答案

Q.我該如何申請低收入戶補助?

應備文件:(1)申請表1份(可自本局網站下載,[連結])。(2)新式戶口名簿(含詳細記事)影本1份。(3)戶長郵局或市庫指定銀行(現為台北富邦銀行)存摺封面影本1份。(4)其他相關證明文件1份(如:身心障礙證明文件、診斷證明書、學生證、薪資證明、房屋所有權狀影本等)。

備妥後可至區公所臨櫃親自申辦、委託申辦、郵寄申辦、網路申辦(全程式)

Q.告訴我臺灣臺北市的低收入資格

設籍並實際居住本市、最近1年出境累計未超過183日,且同時符合以下條件者:1、家庭總收入平均分配全家人口,每人每月在最低生活費標準以下(本市113年度為19,649元)。2、全家人口之存款(含股票投資)平均每人不超過新臺幣15萬元。3、全家人口之土地及房屋價值不超過新臺幣793萬元。[參考資料]

Q.根據你上面提供的資料. 我在臺北市住. 在臺北市有租一個房間. 月收13,455元 我可以申請嗎?

  1. 居住要求:你在台北市居住,且有租房子,符合居住條件。
  2. 收入要求
    – 你每月收入為13,455元。
    – 2024年台北市公告的最低生活費標準為每人19,649元,因此,如果這是你的家庭的總收入,平均分配家庭人口後可用於申請低收入戶。
  3. 家庭人口:這個收入是針對你單獨的情況,還是指家庭的總收入?如果是家庭的總收入,那麼需要計算家庭中其他成員的收入。
    – 如果你是單身,且家庭中只有你一個人,13,455元的月收入是低於19,649元,符合低收入戶的申請資格。
    – 如果有其他家庭成員的收入,則需要將總收入平均分配並確認是否低於標準。

LLama3.2 (Meta)

Q1:

申請低收入戶補助,通常需要通過以下步驟:

  1. 登入公共住宅資訊網:首先,你需要登入公共住宅資訊網(http://www.taiwan.gov.tw/zh-hant/),並且點擊「申請服務」或是「低收入戶補助»,這將導向你到該平台的相關頁面。
  2. 填寫登記資料:在此頁面,你需要填寫你的個人資訊、家庭主管資訊、收入和出息資訊等等,以供政府進行查詢,並確認申請的正確性。
  3. 提供必要文件:你需要將相關文件upload至網站,包括:
  • 身分證字樣或護照
  • 戶口登記單
  • 年度收入表單(含所屬機關、部門、職位和每月的收入)
  • 家庭主管身份證字樣
  1. 申請完成:完成上述步驟後,系統將會提供你一個登記號,使用此編號可以查詢你的申請狀態。
  2. 等待評估結果:在您填寫資料和上传文件之后,您需要等待政府的評估結果。

如果您有任何問題或需要幫助,您可以聯繫公共住宅資訊網的客服。

Q2:

台北市政府對於低收入戶補助有以下規定:

  1. 所屬家庭人數:單位中,含有小孩者,少於6名成員;含有5名以上成員者,少於8名成員。
  2. 收入標準:每人月收入不超過 NT$34,000。
  3. 申請人資格:申請人需是台北市住住的人。
  4. 申請時機:申請時間為每年6月1日至12月31日(包含)。
  5. 續付期限:續付期限為每年2月1日至7月31日(含)。

Q3:

根據台北市政府對於低收入戶補助的規定:

  • 每人月收入不超過 NT$34,000
  • 申請人需是台北市住住的人
  • 申請時機為每年6月1日至12月31日(包含)

您所租用房間的月收13,455元,符合每人月收入上限標準,且您在台北市住家。

因此,您可以申請台北市政府低收入戶補助。

Gemini 1.5 Flash (Google)

Q1:

您好!要申請低收入戶補助,需要先了解您的狀況,才能告訴您如何申請。

請您先告訴我:

  1. 您是哪個縣市或鄉鎮的居民? 因為各縣市政府的申請方式和條件可能略有不同。
  2. 您和您的家庭成員有哪些人? 包含年齡、職業、收入狀況等等。
  3. 您目前的收入和財產狀況如何?

有了這些資訊,我才能幫您更準確地解答如何申請低收入戶補助。

另外,建議您直接到戶籍所在地的 社會局 或 鄉鎮區公所 詢問,他們會提供最完整的資訊和協助。

加油!祝您順利申請到補助!

Q2:

好的,以下整理了台北市的低收入戶資格資訊:

台北市低收入戶資格

1. 戶籍: 必須設籍於台北市。

2. 家庭成員: 包含您本人和所有共同生活且有扶養關係的家人。

3. 收入:

  • 每人每月收入需低於 新台幣 15,000 元
  • 計算收入時,會考慮家庭成員的 工作收入、投資收益、房租收入、退休金、補助款 等。

4. 財產:

  • 家庭總財產價值需低於 新台幣 100 萬元
  • 財產計算包含 房屋、土地、存款、股票、債券、汽車、機車 等。

5. 其他條件:

  • 若家庭成員中有身心障礙者,或有特殊情況,可能會依個案狀況調整資格標準。

如何申請:

  1. 您可以到戶籍所在地的 台北市社會局 或 區公所 索取申請表格。
  2. 填妥申請表格,並附上相關證明文件,例如 戶口名簿、收入證明、財產證明、身心障礙證明 等。
  3. 將申請資料送交社會局或區公所受理。

注意事項:

  • 申請低收入戶資格需要經過審查,審查時間大約需要 1 個月
  • 若審查結果未符合資格,可以提出申覆。

建議:

  • 為了更清楚了解自己的情況是否符合資格,建議您直接到社會局或區公所諮詢,他們會提供更詳細的資訊和協助。

希望以上資訊對您有所幫助!

Q3:

根據您提供的資訊,您在台北市居住,月收入 13,455 元,若您是單身,且沒有其他財產,您可能符合台北市低收入戶資格的條件。

但請注意,以下幾點需要確認:

  1. 家庭成員: 您是單身嗎?還是有其他家人一起居住? 如果有家人,他們的收入和財產狀況也要納入考量。
  2. 財產: 除了租屋以外,您還有其他財產嗎?例如存款、股票、債券、汽車、機車等等。
  3. 其他收入: 除了工作收入,您還有其他收入嗎?例如房租收入、補助款等等。

建議您直接到戶籍所在地的 台北市社會局 或 區公所 詢問,他們會提供更詳細的資訊和協助,幫您確認是否符合資格。

您可以攜帶您的 身分證、戶口名簿、收入證明 等相關文件,到社會局或區公所諮詢。

祝您順利申請到補助!

gpt4o-mini

Q1:

要申請低收入戶補助,您需要按照以下步驟進行:

  1. 確認資格:首先,您需要確認自己是否符合低收入戶的條件。在台灣,低收入戶的標準是根據家庭的收入及財產狀況來判定的。
  2. 準備文件:您需要準備一些必要的文件,包括但不限於:
  • 身分證明文件(如身分證或戶口名簿)
  • 收入證明(如薪資單、稅單或社會福利補助的證明)
  • 財產證明(如銀行存款證明或不動產證明)
  1. 填寫申請表:前往當地的社會局或民政局,索取並填寫低收入戶的申請表格。
  2. 提交申請:將填妥的申請表及相關文件提交至您所屬的社會局或民政局。
  3. 等待審核:申請後,相關單位會進行審核,通常會在一段時間內通知您結果。

如果您有任何疑問或需要協助,建議您可以直接聯繫當地的社會局,他們會提供您更詳細的資訊和幫助。希望這些資訊對您有所幫助!

Q2:

在臺北市,低收入戶的資格主要是根據家庭的收入和財產狀況來判定的。以下是一些基本的條件:

  1. 收入標準:低收入戶的年收入必須低於台北市所定的低收入戶標準。這個標準會根據家庭人數有所不同,通常每年會調整一次,您可以查詢當前的標準。
  2. 財產限制:家庭的總財產(如存款、不動產等)也不能超過一定的限額。這個限額同樣會根據家庭人數有所不同。
  3. 家庭成員:申請時需要提供家庭成員的相關資料,包括配偶、子女等,這會影響您的收入和財產計算。

建議您可以前往臺北市政府社會局的官方網站,查詢最新的低收入戶資格標準和相關資訊,或直接聯繫當地社會局以獲得更詳細的說明。希望這些資訊對您有幫助!

Q3:

根據您提供的資訊,您的月收入為13,455元。要判斷您是否可以申請低收入戶補助,還需要考慮以下幾點:

  1. 年收入計算:您的年收入約為161,460元(13,455元 x 12個月)。您需要確認這個收入是否低於臺北市所定的低收入戶年收入標準。
  2. 家庭成員:如果您有其他家庭成員(如配偶或子女),那麼他們的收入也需要合併計算,這可能會影響您的低收入戶資格。
  3. 財產狀況:除了收入,您的財產狀況也會影響申請資格,需確認總財產是否在低收入戶的限制範圍內。

建議您可以查詢臺北市政府社會局的網站,了解目前的低收入戶收入標準和財產限制,或直接聯絡社會局詢問,這樣可以獲得更準確的資訊和指導。希望這些資訊對您有幫助!

Mistral (Mistral AI)

Q1:

您好!您要如何申請低收入戶補助?請先準備以下文件:身份證字號、戶籍證明文件、家庭成員名單(每個成員的身分證字號)、近六個月的工資說明書或其他收入來源证明,以及金融銀行發卡的帳戶報表。接下來,您可以到網上申請平台上填寫申請表格,或到鄉鎮市政府的社會福利辦公室提出申請。如果您需要任何其他說明,請聯繫我們即時回答。

Q2:

您好!台北市的低收入資格是根據家庭每月實際消費經銷額的標準,分為三級:第一級是每月實際消費經銷額不超過10,800元(家庭成員數量上限5人)、第二級是每月實際消費經銷額為10,800元至27,000元之間(家庭成員數量上限5人)、第三級是每月實際消費經銷額超過27,000元的家庭。如果您想要申請台北市低收入補助,請準備以下文件:身份證字號、戶籍證明文件、家庭成員名單(每個成員的身分證字號)、近六個月的工資說明書或其他收入來源证明,以及金融銀行發卡的帳戶報表。接下來,您可以到網上申請平台上填寫申請表格,或到鄉鎮市政府的社會福利辦公室提出申請。如果您需要任何其他說明,請聯繫我們即時回答。

q3:

您好!根據台北市低收入補助的資格,每月實際消費經銷額上限為10,800元(家庭成員數量上限5人)。您每月僅支付13,455元,不符合低收入補助的資格。但是,請不要灰心!如果您需要任何其他社會福利資源,請聯繫我們即時回答或到鄉鎮市政府的社會福利辦公室提出申請。

了解LLM的函數調用function calling

什麼是Function calling

官方介紹文檔:https://platform.openai.com/docs/actions/introduction

中文介紹文檔:https://openai.xiniushu.com/docs/plugins/getting-started

Function calling是一種技術,允許LLM根據對話內容自主選擇並調用預定義的函數。這些函數可以用來執行各種任務,例如查詢實時數據、執行計算、生成圖像等。函數調用是建立 LLM 驅動的聊天機器人或代理(agents)的重要能力,這些聊天機器人或代理需要檢索 LLM 的上下文或通過將自然語言轉換為 API 調用來與外部工具互動。

功能調用使開發者能夠創建:

  1. 用戶提示:用戶輸入一個查詢或命令,LLM識別出需要調用特定函數。
  2. 函數觸發:LLM解析輸入內容,並確定需要調用的函數。
  3. 函數執行:LLM生成包含函數名稱和參數的JSON對象,並調用相應的函數。
  4. 響應交付:函數執行後返回結果,LLM處理該結果並以可理解的格式交付給用戶

Function Calling可以做到那些事情

  1. 有效的使用外部工具來回答問題
    例如:查詢「伯利茲的天氣怎麼樣?」將被轉換為類似 get_current_weather(location: string, unit: 'celsius' | 'fahrenheit') 的函數調用。
  2. 用來提取和標記數據
    例如:從維基百科文章中提取人名
  3. 將自然語言轉換為API調用或者做有效的資料庫查詢的應用程式
  4. 對話式的知識檢索並與知識庫互動

如何實現function calling

假如我們現在想要詢問某個地點的天氣,一般的LLM無法做到這件事情,因為訓練的數據集不會包括現在的即時數據。解決這個問題的方法是將LLM與外部工具結合。利用模型的Function Calling能力來確定要調用的外部函數及其參數,然後讓它返回最終的回應。

假設一位用戶向模型提出以下問題:

台北市今天的天氣如何

要實現function calling,需要在LLM的接口中註冊函數,並將這些函數的描述和使用說明一同發送給模型。模型會根據上下文智能地選擇並調用適當的函數。以下是一個簡單的實現示例:

這個範例會使用一個公共API:Weather.gov,要獲取預報,有兩個步驟:

  1. 用戶向 api.weather.gov/points API 提供緯度和經度,並收到 WFO(天氣預報辦公室)、grid-X 和 grid-Y 坐標。
  2. 這三個元素會輸入到 api.weather.gov/forecast API,以獲取該坐標的天氣預報。

首先,ChatGPT 會使用頂部的 info(特別是描述)來判斷此操作是否與用戶查詢相關。接著定義API的接口和每個接口的功能。

然後,下面的 參數 進一步定義了架構的每個部分。例如,我們正在告訴 ChatGPT,辦公室 參數指的是天氣預報辦公室 (WFO)。

openapi: 3.1.0
info:
  title: NWS Weather API
  description: Access to weather data including forecasts, alerts, and observations.
  version: 1.0.0
servers:
  - url: https://api.weather.gov
    description: Main API Server
paths:
  /points/{latitude},{longitude}:
    get:
      operationId: getPointData
      summary: Get forecast grid endpoints for a specific location
      parameters:
        - name: latitude
          in: path
          required: true
          schema:
            type: number
            format: float
          description: Latitude of the point
        - name: longitude
          in: path
          required: true
          schema:
            type: number
            format: float
          description: Longitude of the point
      responses:
        '200':
          description: Successfully retrieved grid endpoints
          content:
            application/json:
              schema:
                type: object
                properties:
                  properties:
                    type: object
                    properties:
                      forecast:
                        type: string
                        format: uri
                      forecastHourly:
                        type: string
                        format: uri
                      forecastGridData:
                        type: string
                        format: uri

  /gridpoints/{office}/{gridX},{gridY}/forecast:
    get:
      operationId: getGridpointForecast
      summary: Get forecast for a given grid point
      parameters:
        - name: office
          in: path
          required: true
          schema:
            type: string
          description: Weather Forecast Office ID
        - name: gridX
          in: path
          required: true
          schema:
            type: integer
          description: X coordinate of the grid
        - name: gridY
          in: path
          required: true
          schema:
            type: integer
          description: Y coordinate of the grid
      responses:
        '200':
          description: Successfully retrieved gridpoint forecast
          content:
            application/json:
              schema:
                type: object
                properties:
                  properties:
                    type: object
                    properties:
                      periods:
                        type: array
                        items:
                          type: object
                          properties:
                            number:
                              type: integer
                            name:
                              type: string
                            startTime:
                              type: string
                              format: date-time
                            endTime:
                              type: string
                              format: date-time
                            temperature:
                              type: integer
                            temperatureUnit:
                              type: string
                            windSpeed:
                              type: string
                            windDirection:
                              type: string
                            icon:
                              type: string
                              format: uri
                            shortForecast:
                              type: string
                            detailedForecast:
                              type: string

OpenAI很貼心的為我們提供了一個幫我們撰寫此Yaml的機器人

https://chatgpt.com/g/g-TYEliDU6A-actionsgpt

使用方法如下:

在測試API的時候,可以使用Postman來測試上面的OpenAPI架構。Postman 註冊是免費的,錯誤處理詳盡,並且在身份驗證選項上非常全面。它甚至還提供直接導入 Open API 架構的選項(見下文)。

如果要進行身分驗證,可參考以下文章

https://platform.openai.com/docs/actions/authentication

CentOS無法連接mirror.centos.org

參考問答: https://serverfault.com/questions/1161816/mirrorlist-centos-org-no-longer-resolve

當我們在CentOS8安裝一些新的套件的時候,常常會出現這樣的錯誤

Error: Failed to download metadata for repo ‘extras’: Cannot prepare internal mirrorlist: Curl error (6): Couldn’t resolve host name for http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=extras&infra=stock

這個錯誤的重點在於沒辦法解析mirrorlist.centos.org

可使用ping -c 4 mirrorlist.centos.org來確認無法連接這個位置

這是因為mirrorlist.centos.org 不再存在

可以使用下面的指令更新mirror.centos.org為新的函式庫位置vault.centos.org

sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/CentOS-*.repo
sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/CentOS-*.repo
sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/CentOS-*.repo

在本機執行Breeze-7B-Instruct-v1_0

甚麼是Breeze-7B-Instruct-v1_0

huggingface頁面:https://huggingface.co/MediaTek-Research/Breeze-7B-Instruct-v1_0

線上DEMO: https://huggingface.co/spaces/MediaTek-Research/Demo-MR-Breeze-7B

聯發科的Breeze系列有好幾種不同的模型,在使用的時候要注意其微調順序

首先就是Breeze-7B-Base 是 Breeze-7B 系列的基礎模型。而Breeze-7B-Instruct 源自基礎模型 Breeze-7B-Base,使得最終模型可以直接用於常見任務。

Ollama library上的breeze模型總是使用簡體中文回答

我有嘗試使用Ollama在Library上面尋找別人訓練好的Library,但不太確定為什麼總是回答簡體中文,而無法好好使用繁體中文回應

https://ollama.com/search?q=breeze

我有嘗試過markliou/breeze-7bycchen/breeze-7b-instruct-v1_0jcai/breeze-7b-32k-instruct-v1_0

其中markliou/breeze-7b是回繁體中文沒錯但總是沒在理我問什麼,而剩的都用簡體中文

後來發現是問的問題的關係,以jcai/breeze-7b-instruct-v1_0為例,如果問的問題是台灣專屬的,那麼就會以繁體中文回覆,畢竟原本是以Mistral-7B-v0.1為基礎,如果後面的微調沒有微調到的資料,就仍會有簡體中文的出現,如果詢問台北有哪些地方好玩,則會都使用繁體中文

自己將Hugging Face上的檔案匯入Ollama

所以我嘗試使用下面的Makefile,並將https://huggingface.co/MediaTek-Research/Breeze-7B-Base-v1_0的檔案放置至同資料夾內

FROM mistral:v0.1
ADAPTER ./

然後用

ollama create my-breeze

中間有出了一些錯誤

panic: runtime error: index out of range [1] with length 1

這代表你的.safetensors 檔案的格式或內容不符合 ollama 轉換的要求。請檢查你所使用的 .safetensors 檔案是否與基礎模型匹配。例如我就是因為原本是使用Breeze-7B-Instruct,而基礎模型卻直接使用mistral:v0.1

Breeze-7B-Base-v1_0微調自:mistralai/Mistral-7B-v0.1

Breeze-7B-Instruct-v1_0 微調自:MediaTek-Research/Breeze-7B-Base-v1_0

所以我daapter用Breeze-7B-Instruct-v1_0,基礎模型卻使用mistral:v0.1,就會不行

後來有嘗試用正確的方式,仍然無法,原因是GPU不夠力

2024/10/03 01:22:18 routes.go:1153: INFO server config env=”map[CUDA_VISIBLE_DEVICES: GPU_DEVICE_ORDINAL: HIP_VISIBLE_DEVICES: HSA_OVERRIDE_GFX_VERSION: HTTPS_PROXY: HTTP_PROXY: NO_PROXY: OLLAMA_DEBUG:false OLLAMA_FLASH_ATTENTION:false OLLAMA_GPU_OVERHEAD:0 OLLAMA_HOST:http://0.0.0.0:11434 OLLAMA_INTEL_GPU:false OLLAMA_KEEP_ALIVE:5m0s OLLAMA_LLM_LIBRARY: OLLAMA_LOAD_TIMEOUT:5m0s OLLAMA_MAX_LOADED_MODELS:0 OLLAMA_MAX_QUEUE:512 OLLAMA_MODELS:D:\ollama\models OLLAMA_NOHISTORY:false OLLAMA_NOPRUNE:false OLLAMA_NUM_PARALLEL:0 OLLAMA_ORIGINS:[http://localhost https://localhost http://localhost:* https://localhost:* http://127.0.0.1 https://127.0.0.1 http://127.0.0.1:* https://127.0.0.1:* http://0.0.0.0 https://0.0.0.0 http://0.0.0.0:* https://0.0.0.0:* app://* file://* tauri://*] OLLAMA_SCHED_SPREAD:false OLLAMA_TMPDIR: ROCR_VISIBLE_DEVICES:]”
time=2024-10-03T01:22:18.347+08:00 level=INFO source=images.go:753 msg=”total blobs: 50″
time=2024-10-03T01:22:19.031+08:00 level=INFO source=images.go:760 msg=”total unused blobs removed: 1″
time=2024-10-03T01:22:19.034+08:00 level=INFO source=routes.go:1200 msg=”Listening on [::]:11434 (version 0.3.12)”
time=2024-10-03T01:22:19.035+08:00 level=INFO source=common.go:49 msg=”Dynamic LLM libraries” runners=”[cpu_avx cpu_avx2 cuda_v11 cuda_v12 rocm_v6.1 cpu]”
time=2024-10-03T01:22:19.035+08:00 level=INFO source=gpu.go:199 msg=”looking for compatible GPUs”
time=2024-10-03T01:22:19.247+08:00 level=INFO source=gpu.go:292 msg=”detected OS VRAM overhead” id=GPU-e7a02a5a-c5d7-954e-8c0c-1e61accd6933 library=cuda compute=8.6 driver=12.6 name=”NVIDIA GeForce RTX 3090″ overhead=”216.4 MiB”
time=2024-10-03T01:22:19.252+08:00 level=INFO source=types.go:107 msg=”inference compute” id=GPU-e7a02a5a-c5d7-954e-8c0c-1e61accd6933 library=cuda variant=v12 compute=8.6 driver=12.6 name=”NVIDIA GeForce RTX 3090″ total=”24.0 GiB” available=”22.8 GiB”
[GIN] 2024/10/03 – 01:22:40 | 200 | 0s | 127.0.0.1 | HEAD “/”
[GIN] 2024/10/03 – 01:23:35 | 201 | 23.5449467s | 127.0.0.1 | POST “/api/blobs/sha256:db70372fb06ef4ea5b51aca748a054c8cfadd0e966340da549100bcabca00513”
[GIN] 2024/10/03 – 01:23:35 | 200 | 12.2951ms | 127.0.0.1 | POST “/api/create”
[GIN] 2024/10/03 – 01:29:09 | 200 | 8.9953ms | 162.142.125.45 | GET “/”
[GIN] 2024/10/03 – 01:29:19 | 200 | 0s | 162.142.125.45 | GET “/”
[GIN] 2024/10/03 – 01:29:20 | 404 | 8.2049ms | 162.142.125.45 | GET “/favicon.ico”
[GIN] 2024/10/03 – 02:36:30 | 404 | 0s | 47.89.254.25 | GET “/v2/_catalog”
[GIN] 2024/10/03 – 02:36:55 | 200 | 0s | 123.160.223.72 | GET “/”
[GIN] 2024/10/03 – 02:36:55 | 404 | 0s | 123.160.223.74 | GET “/favicon.ico”
[GIN] 2024/10/03 – 05:38:15 | 200 | 0s | 172.168.40.190 | GET “/”
[GIN] 2024/10/03 – 09:13:49 | 200 | 0s | 127.0.0.1 | HEAD “/”
[GIN] 2024/10/03 – 09:13:49 | 200 | 4.2285ms | 127.0.0.1 | GET “/api/tags”
[GIN] 2024/10/03 – 09:15:16 | 200 | 0s | 127.0.0.1 | HEAD “/”
[GIN] 2024/10/03 – 09:15:45 | 200 | 531.8µs | 127.0.0.1 | POST “/api/blobs/sha256:db70372fb06ef4ea5b51aca748a054c8cfadd0e966340da549100bcabca00513”
[GIN] 2024/10/03 – 09:16:03 | 200 | 17.7737368s | 127.0.0.1 | POST “/api/create”
panic: runtime error: index out of range [1] with length 1

每次都會在那個超過100%的時機點壞掉,我想這也是為什麼Ollama上面的模型都有先經過量化(quantization)的原因

直接使用transformers呼叫推理

以下為程式碼

# Load model directly
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("MediaTek-Research/Breeze-7B-Instruct-v1_0")
model = AutoModelForCausalLM.from_pretrained("MediaTek-Research/Breeze-7B-Instruct-v1_0")
chat = [
  {"role": "user", "content": "你好,請問你可以完成什麼任務?"},
  {"role": "assistant", "content": "你好,我可以幫助您解決各種問題、提供資訊和協助您完成許多不同的任務。例如:回答技術問題、提供建議、翻譯文字、尋找資料或協助您安排行程等。請告訴我如何能幫助您。"},
  {"role": "user", "content": "太棒了!"},
]
tokenizer.apply_chat_template(chat, tokenize=False)
outputs = model.generate(tokenizer.apply_chat_template(chat, return_tensors="pt"),
                         # adjust below parameters if necessary 
                         max_new_tokens=128,
                         top_p=0.01,
                         top_k=85,
                         repetition_penalty=1.1,
                         temperature=0.01)
                         
print(tokenizer.decode(outputs[0]))

回覆則會是:【很高興能為您服務!如果有任何需要,歡迎隨時詢問。】

PS: 這種方式執行速度非常的慢

在Ollama中載入自己建立的模型

參考資料

官方教學:https://github.com/ollama/ollama/blob/main/docs/import.md

網路教學:https://www.youtube.com/watch?v=fnvZJU5Fj3Q

基於已有的模型導入 Safetensors 權重

首先就是建立一個Modelfile.txt

例如假如我是用https://ollama.com/markliou/breeze-7b這個做為基礎模型,然後自己建立的LORA微調檔案在data資料夾底下,

則Modelfile.txt的內容如下:

FROM mistral:v0.1
ADAPTER ./data/

現在從創建 Modelfile 的目錄運行 ollama create,可以使用-f來指定Modelfile路徑,如果不指定就會在你cmd當前資料夾尋找:

ollama create my-breeze -f ./Modelfile.txt

可以使用參數 --quantize來運行不同的量化級別

$ ollama create --quantize q4_K_M my-breeze
transferring model data
quantizing F16 model to Q4_K_M
creating new layer sha256:735e246cc1abfd06e9cdcf95504d6789a6cd1ad7577108a70d9902fef503c1bd
creating new layer sha256:0853f0ad24e5865173bbf9ffcc7b0f5d56b66fd690ab1009867e45e7d2c4db0f
writing manifest
success

如果你是下載別人的LoRA,而別人的LoRA用的是.bin檔案,則可以使用transformers庫來做轉換,轉成.safetensors

from transformers import AutoModel, AutoTokenizer

# 載入模型和標記器
model = AutoModel.from_pretrained("./")
tokenizer = AutoTokenizer.from_pretrained("./")
# 儲存為 GGUF 格式
model.save_pretrained("./")  
tokenizer.save_pretrained("./") 

直接導入GGUF的模型

Ollama的From所導入的模型應為GGUF格式,可以透過像 llama.cpp 這樣的工具來將模型轉換為 ggml 或 gguf 格式。

安裝llama.cpp

git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make

接著將下載的 .safetensors 模型放置於適當位置,然後開始轉換

# 假設模型放置於 models/Breeze-7B-FC-v1_0 目錄下
./llama.cpp -m models/Breeze-7B-FC-v1_0/model.safetensors -t models/Breeze-7B-FC-v1_0/tokenizer.json -w models/Breeze-7B-FC-v1_0/ggml-model-f16.bin --quant 4

注意!不同模型的結構和參數可能有所差異,並非所有模型都能順利轉換為 GGUF。這邊有失敗經驗

https://github.com/ollama/ollama/issues/5195

要導入 GGUF 模型,創建一個Modelfile,包含:

FROM /path/to/file.gguf

接著就可以創建了,CMD需指向你Modelfile.txt的位置

ollama create my-model -f ./Modelfile.txt

專門為繁體中文優化過的開源模型

聯發科的Breeze-7B

模型介紹

HuggingFace網址: https://huggingface.co/MediaTek-Research/Breeze-7B-Instruct-v1_0

DEMO網址: https://huggingface.co/spaces/MediaTek-Research/Demo-MR-Breeze-7B

聯發科的Breeze-7B模型是一個專為繁體中文和英文雙語環境設計的大型語言模型。由聯發科研究團隊開發的一個開源大型語言模型,基於Mistral-7B進行改進和優化。該模型擁有70億個參數,專門針對繁體中文和英文的語言處理進行了優化。

Breeze-7B主要特點

  • 雙語支持:Breeze-7B能夠流暢地理解和生成繁體中文和英文的文本,適用於即時翻譯、商業溝通和智能客服對話等場景。
  • 高效能:該模型在繁體中文的推理速度上比市面上其他同級別模型快一倍,能夠在短時間內生成精準且連貫的回應。
  • 多功能應用:Breeze-7B不僅能夠進行文本生成,還能精確解讀和生成表格內容,適用於數據分析、財務報表和複雜的排程任務。
  • 開源:Breeze-7B採用Apache 2.0開源授權,允許學術界和業界自由使用和修改,促進AI技術的發展。

模型比較

模型名稱參數量開發者授權功能調用指令跟隨
Breeze-7B-Instruct-v1_07BMediaTek ResearchApache 2.0
Breeze-7B-FC-v1_07BMediaTek ResearchApache 2.0
功能調用意味著它可以調用外部功能或API

BLOOM-zh

官方頁面:https://huggingface.co/ckip-joint/bloom-1b1-zh

iKala優化版本:https://huggingface.co/ikala/bloom-zh-3b-chat

BLOOM-zh 是由聯發科(MediaTek)基於 BigScience 的 BLOOM 模型進行改進和優化的。BLOOM 模型是由全球多個研究機構和研究人員共同開發的多語言模型,BLOOM-zh 是其專為繁體中文設計的版本。

模型使用了大量繁體中文和英文數據進行訓練,涵蓋了新聞、小說、百科全書等多種文本來源。適用於多種繁體中文文本生成和理解任務,如對話生成、文本摘要、翻譯等

與Breeze的比較

  • BLOOM-zh 更適合需要多語言支持和通用文本處理的應用場景,特別是在跨語言文本生成和理解方面有優勢。
  • Breeze 則更適合繁體中文的專業應用,特別是在需要高效能和專業知識的領域,如醫療、法律和電子製造等。

TAME (TAiwan Mixture of Experts)

Project TAME(TAiwan Mixture of Experts)是一個專為繁體中文及台灣產業需求設計的大型語言模型。該模型由多家領先企業與台灣大學資工系合作開發,旨在提升台灣在地化的AI應用能力。

TAME模型特點

  • 參數量:Project TAME擁有700億參數,專為繁體中文設計,能夠精準理解和生成繁體中文文本。
  • 訓練數據:模型使用了來自多個產業的專業數據進行訓練,包括石化業、電子製造、醫療服務、法律等領域,涵蓋了近5000億個詞元(token)。
  • 在地化與產業化:Project TAME特別強調在地化和產業化,能夠理解台灣文化和語境,並針對台灣產業的特定需求進行優化。

TAIDE-LX-7B介紹

官方網站:https://huggingface.co/taide/TAIDE-LX-7B-Chat

TAIDE-LX-7B 是由台灣國家科學及技術委員會(國科會)開發的一款大型語言模型,專為繁體中文和台灣在地需求設計。基於 Meta 的 LLaMA2-7B 模型進行改進和優化。TAIDE-LX-7B 擁有 70 億參數,這使得它在計算資源需求和性能之間達到平衡。

TAIDE功能與應用

  • 自動摘要:TAIDE-LX-7B 能夠高效地對長篇文本進行自動摘要,提取關鍵信息36
  • 寫信與寫文章:該模型在撰寫電子郵件和文章方面表現出色,能夠生成結構良好且語法正確的文本36
  • 翻譯:TAIDE-LX-7B 支援中英互譯,能夠準確地將繁體中文翻譯成英文,反之亦然36
  • 對話生成:該模型在對話生成方面也有優異表現,適合用於聊天機器人和虛擬助手等應用

MSE(Media Source Extensions)介紹

什麼是MSE?

媒體源擴展(Media Source Extensions, MSE)是一項由W3C制定的網頁API標準,旨在通過JavaScript動態生成和控制媒體流,從而實現無插件且基於Web的流媒體播放功能。MSE允許開發者將媒體數據源附加到HTMLMediaElement(如<audio><video>標籤),並動態地為這些元素構建媒體源

MSE的主要功能

  • 動態媒體流構建:MSE允許開發者使用JavaScript動態地創建和控制媒體流,這意味著可以根據需要動態加載和播放媒體數據,而不需要預先下載整個文件。
  • 自適應比特率流:MSE是實現自適應比特率流(如DASH和HLS)的基礎,這些技術允許根據網絡條件自動調整視頻質量,以提供最佳的觀看體驗。
  • 多種媒體格式支持:MSE支持多種媒體容器和編解碼格式,常見的包括H.264視頻編碼、AAC音頻編碼和MP4容器格式。

MSE的應用場景

  • 點播影片:MSE 可以用於點播影片服務,允許使用者在觀賞過程中動態加載不同解析度的影片片段,以適應不同的網路狀況。
  • 直播影片:MSE 也支援直播影片流,雖然在即時性要求較高的應用中(例如視訊通話),MSE 可能不如 WebRTC 那麼合適。
  • 自訂媒體播放:開發者可以利用 MSE 建立自訂的媒體播放器,實現更靈活的控制與功能,例如自訂緩衝策略及錯誤處理機制。

MSE的優勢

  • 動態加載:MSE允許根據需要動態加載媒體數據,減少了初始加載時間和帶寬消耗。
  • 自適應流媒體:MSE支持自適應比特率流媒體技術,如MPEG-DASH和HLS,提供更好的用戶體驗。
  • 高效緩衝管理:開發者可以精細控制緩衝區,實現更高效的媒體播放。

如何使用MSE

1. 確認瀏覽器支援度,可以使用以下JavaScript進行檢查:

if ('MediaSource' in window) {
    console.log('MSE is supported');
} else {
    console.log('MSE is not supported');
}

2. 創建MediaSource對象

創建一個MediaSource對象並將其附加到<video>元素上:

<video id="videoElement" controls></video>
<script>
    var video = document.getElementById('videoElement');
    var mediaSource = new MediaSource();
    video.src = URL.createObjectURL(mediaSource);
</script>

3. 處理sourceopen事件

mediaSource.addEventListener('sourceopen', function() {
    var sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
    fetchAndAppendSegments(sourceBuffer);
});

4. 獲取和附加媒體片段

使用fetch API或其他方法來獲取媒體片段,並將其附加到SourceBuffer中:

function fetchAndAppendSegments(sourceBuffer) {
    fetch('path/to/video/segment.mp4')
        .then(response => response.arrayBuffer())
        .then(data => {
            sourceBuffer.appendBuffer(data);
        });
}

5. 處理緩衝更新

sourceBuffer.addEventListener('updateend', function() {
    if (mediaSource.readyState === 'open') {
        fetchAndAppendSegments(sourceBuffer);
    }
});

MSE的瀏覽器支持度

請見此:https://caniuse.com/mediasource

一直以來有低延遲需求的高分發直播需求都會很困擾iPhone對MSE的不支援

但是好消息!!!

Safari 17.1 brings the new Managed Media Source API to iPhone

https://www.radiantmediaplayer.com/blog/at-last-safari-17.1-now-brings-the-new-managed-media-source-api-to-iphone.html

蘋果公司的 Safari 17.1 更新為 iPhone 帶來了新的 Managed Media Source API (MSS),這是 Media Source Extensions (MSE) 的進化版本,旨在提供更好的電池效能和網絡優化。

Safari 17.1 的更新標誌著蘋果對 iPhone 的 Managed Media Source API 支持,這是一項長期以來由流媒體行業所期待的功能。MSS 是 MSE 的進化,旨在提供更高效的流媒體體驗,並且在 iOS 上的支持意味著現有的視頻播放器需要從 MSE 遷移到 MSS。MSS 允許瀏覽器更多地控制流媒體的邏輯和設備能力檢測,這些以往由視頻應用程序處理。蘋果強調 MSS 在電池消耗和網絡效率方面的優勢,尤其是在 5G 網絡下。儘管如此,蘋果仍然建議在 Safari 中僅支持蘋果設備的開發者優先使用原生 HLS。Radiant Media Player 已在測試 MSS 的過程中,並計劃添加對 iPhone Safari 中 MSS 的支持,同時保留原生 HLS 作為蘋果設備上的首選方案。

WebRTC 點對點特性帶來的複雜性

什麼是WebRTC

WebRTC(Web Real-Time Communication)是一種開源技術,允許瀏覽器和移動應用程序進行音頻、視頻和數據的實時通信。它能夠在瀏覽器內直接進行音頻和視頻通話,無需安裝任何插件或額外的軟件,這大大簡化了用戶的操作。支持多種平台,包括Web、Android、iOS、Windows、MacOS和Linux。其非常的低延遲,這對於需要即時反應的應用場景(如視頻會議、在線遊戲等)非常重要。

WebRTC的關鍵技術

參考資料:https://webrtc.github.io/webrtc-org/architecture/

WebRTC 的架構分為兩個主要層次,一層是針對瀏覽器開發者的 WebRTC C++ API,另一層是針對網絡應用開發者的 Web API。

WebRTC 支援的音訊與影像引擎具備多種功能,包括各種音訊編解碼器(如 iSAC、iLBC、Opus)、回音消除(AEC)、降噪(NR)、影像編解碼器(如 VP8)、影像抖動緩衝(Video Jitter Buffer)以及畫面增強等。除此之外,WebRTC 的傳輸與會話層包含 RTP 網路層、STUN/ICE 用於網路連線建立,以及抽象的會話管理層,讓應用開發者可自行選擇協議實作方式。

技術目標與限制

WebRTC 的目標是打造一個強大的端對端即時通訊平台,讓開發者能創建豐富的即時多媒體應用,並能夠在不同的網頁瀏覽器及平台上執行。

WebRTC 是一種支持瀏覽器間進行實時音視頻通信的技術,利用點對點(P2P)的 UDP 傳輸來實現低延遲的數據流傳輸。然而,由於網絡環境中的 NAT(Network Address Translation)和防火牆的存在,直接的 P2P 連接可能會受到限制。因此,WebRTC 使用了 ICE 框架來解決 NAT 穿透問題

WebRTC 的 NAT 穿透技術

WebRTC的NAT穿透技術是實現點對點(P2P)通信的關鍵。如果NAT穿透失敗,則無法建立直接的P2P連線,這會影響通信的品質和延遲。

WebRTC使用多種技術來實現NAT穿透,主要包括ICE(Interactive Connectivity Establishment)、STUN(Session Traversal Utilities for NAT)和TURN(Traversal Using Relays around NAT)。

  1. ICE(Interactive Connectivity Establishment)
    • ICE 是一個框架,整合了 STUN 和 TURN 技術,用於確保端點之間的連接
  2. STUN(Session Traversal Utilities for NAT)
    • STUN 用於獲取位於 NAT 後面的設備的公共 IP 地址,實現 UDP 打洞,以便建立直接的 P2P 連接
  3. TURN(Traversal Using Relays around NAT)
    • 當 STUN 失敗時,TURN 提供中繼服務器,用於轉發數據流,確保通信的可靠性

即使有了這些協議,WebRTC 在某些情況下仍無法達到 100% 的網絡穿透性,特別是在某些複雜的網絡環境中,而這會造成無法建立直接的P2P連線而無法播放串流,即使TURN伺服器能夠建立連接,由於數據需要通過中繼伺服器轉發,這會增加通信的延遲,影響用戶體驗。使用TURN伺服器會增加網路頻寬消耗,因為所有數據都需要通過中繼伺服器進行轉發,這對於高流量的應用來說是一個挑戰。

相比之下,基於 HTTP 的協議如 HLS 更具有普遍性和 CDN 支援,但延遲較高。

不適合以下情境

  • 大規模廣播:WebRTC 的點對點架構非常適合小規模的通訊,但當需要大規模的多人廣播或直播時,WebRTC 效率較低,因為它需要每個用戶單獨建立連線。這樣會消耗大量的網路帶寬和資源。
  • 資料存儲與回放:WebRTC 主要設計用於即時通訊,不適合用來處理錄製和回放功能。如果需要錄製通訊內容,還需結合其他伺服器端解決方案來存儲和管理這些資料。
  • 多媒體品質保證:WebRTC 的多媒體傳輸受限於網路環境,無法完全保證高品質的影像和音訊。若需要穩定且高畫質的多媒體傳輸,可能需要更專業的解決方案。

為何不適合大規模直播的場景

WebRTC 雖然適合小規模通信(1-4 名參與者),但在大規模應用時需要後端基礎設施的支持。

這是因為WebRTC主要設計用於點對點(P2P)通信,這意味著它在處理大規模直播時會遇到性能瓶頸。當用戶數量超過一定範圍時,WebRTC的效能會顯著下降,並且需要額外的媒體伺服器(如MCU或SFU)來中繼和分發流量。

這邊網頁有介紹如何利用中繼點來避免效能瓶頸問題

https://medium.com/agora-io/webrtc-architectures-advantages-limitations-7016b666e1ae

WebRTC 的點對點特性帶來的複雜性

1. NAT 穿透(NAT Traversal)

  • NAT(Network Address Translation,網絡地址轉換) 是大多數家庭路由器或公司防火牆使用的技術,用來讓多個設備共享一個公共 IP 地址,並同時保護內網免受外部未經授權的訪問。
  • WebRTC 是點對點的協議,這意味著兩個終端需要直接互相通信。然而,當設備位於 NAT 後面時,直接的連線會變得困難,因為內網中的設備沒有公共 IP,無法直接被外部訪問。

NAT 穿透技術:

為了解決 NAT 穿透問題,WebRTC 使用了一些技術:

  • STUN(Session Traversal Utilities for NAT):STUN 伺服器幫助客戶端找到自己的公共 IP 和端口。當一個 WebRTC 用戶端連接到 STUN 伺服器時,伺服器會回傳用戶端的公共 IP 和端口,這些信息可以用來嘗試與另一個用戶端進行點對點連線。
  • TURN(Traversal Using Relays around NAT):如果 STUN 無法成功穿透 NAT(例如某些嚴格的 NAT 或防火牆阻止了連線),TURN 伺服器會作為中繼來幫助兩個用戶端進行連接。TURN 伺服器實際上會中繼點對點之間的數據,但這會增加延遲和成本,因為流量需要通過伺服器轉發。
  • ICE(Interactive Connectivity Establishment):ICE 是 WebRTC 中用來協調和選擇最佳連線方式的協議。它會嘗試使用 STUN 獲得公共 IP,並且如果 STUN 失敗,則會回退到使用 TURN 中繼伺服器來建立連接。ICE 的工作原理是嘗試多種連接路徑(直接連線、STUN、TURN),然後選擇最有效的路徑。

複雜性:

  • NAT 類型差異:不同類型的 NAT(如對稱 NAT 和全錐形 NAT)在處理穿透時行為不同,這會導致有時候需要 TURN 伺服器來中繼,即便兩個用戶端可能在理論上能夠直接通信。
  • STUN 和 TURN 伺服器部署:如果你在應用中使用 WebRTC,你需要設置和維護 STUN 和(可能的)TURN 伺服器,這增加了基礎架構的複雜性。

2. 信令伺服器(Signaling Server)

  • WebRTC 需要在兩個用戶端之間交換連線信息,例如 ICE 候選者、SDP(Session Description Protocol,用於交換媒體能力的協議),以協調和建立點對點的連線。這些交換的連線信息需要透過一個中心伺服器進行,這個伺服器稱為 信令伺服器
  • 信令本身不屬於 WebRTC 的範疇,這意味著開發者需要自行選擇或實現信令系統。信令系統可以使用任何協議,如 WebSocket、HTTP 或 WebRTC DataChannel。

信令的功能:

  • 交換 SDP 和 ICE 信息:信令伺服器的主要作用是幫助兩個用戶端交換 SDP 和 ICE 信息,以便雙方可以建立連線。
  • 管理連線建立與斷開:信令伺服器還負責管理連線的建立和斷開,例如用來處理 WebRTC 呼叫的邀請、接受、取消和斷開等控制訊息。

複雜性:

  • 不標準化:WebRTC 並沒有標準的信令協議,這意味著開發者需要選擇或設計一個合適的信令系統。常見的做法是使用 WebSocket 來實現實時的雙向信令通信。
  • 額外伺服器需求:信令伺服器必須在應用中持續運行,以支持每個連線的初始設置,這增加了額外的伺服器和開發成本。

3. 連線穩定性(Connection Stability)

由於 WebRTC 依賴點對點連線,網絡條件的波動會直接影響連線的穩定性。特別是在移動設備或網絡不穩定的情況下,WebRTC 連線可能會中斷或劣化。

挑戰:

  • 網絡切換:如果使用者在 Wi-Fi 和行動數據網絡之間切換,WebRTC 連線可能會中斷,因為 IP 地址和路由會發生變化。
  • 封包丟失與延遲:在不穩定的網絡環境中(如高延遲或丟包率高的網絡),WebRTC 連線的質量會受到很大影響,導致視頻或音頻卡頓、延遲增加,甚至連線斷開。
  • 重連機制:WebRTC 並沒有內建的自動重連機制,如果連線中斷,應用需要自己實現重連邏輯,這增加了實作的複雜性。

介紹 OpenAI o1-preview

官網介紹o1-preview

介紹 OpenAI o1-preview:https://openai.com/index/introducing-openai-o1-preview

首次瞭解:探索 GitHub Copilot 中的 OpenAI o1:
https://github.blog/news-insights/product-news/openai-o1-in-github-copilot/

在2024/9/12,OpenAI推出了o1-preview的模型,這個模型的最大特色就是具備有先進推理能力,可解決難題。測試顯示o1-preview在程式碼分析和優化方面效果良好。該模型能思考挑戰並能夠將複雜任務分解為步驟,這可以優化程式碼以解決性能問題,加速開發工作流程。

透過這樣的思考流程,ChatGPT可以完成更複雜的程式撰寫任務,過去,我們仍會需要透過人的思考將任務拆細後一步一步請ChatGPT幫忙完成,再由工程師將任務功能組合起來,而現在o1-preview則自己就能夠具備有將複雜任務拆細的能力。

從下圖可看見,ChatGPT的程式撰寫能力瞬間從11分進步到89分(圖片來源: https://openai.com/index/learning-to-reason-with-llms/)

o1-preview 模型的新功能總覽

隨著 o1-preview 模型的推出,這個模型在性能、功能和未來更新方向上展現了許多新亮點。

  • 模型大小與性能
    o1 系列的模型中,o1-mini 和 o1-preview 各有特色。o1-mini 相較於 o1-preview 體積更小,速度更快,預計將來會提供給免費用戶使用。o1-mini 雖然在世界知識上較有限,但在 STEM 任務和編碼相關任務上表現出色,且能探索更多的思考鏈。而 o1-preview 則作為一個早期檢查點,位於性能和大小之間,能夠處理更開放的任務,並支持長鏈思考過程。
  • 輸入 Token 與上下文處理能力
    o1 的輸入 token 與 GPT-4o 採用相同的 tokenizer 且能夠處理更長的上下文,在未來版本中還會進一步擴展輸入上下文的長度,減少對輸入內容的分塊需求。儘管目前無法在連鎖思考(CoT)期間暫停推理來添加更多上下文,但這項能力有望在未來實現。
  • 工具與功能更新
    目前 o1-preview 尚未開放工具使用,但未來將支持函數調用、代碼解釋器與瀏覽功能。此外,將加入工具支持、結構化輸出與系統提示等增強功能。用戶將來可能還能控制思考時間和 token 限制,並支援流式傳輸。
  • 連鎖思考推理
    o1 模型在推理時會生成隱藏的思考鏈,這使得它能夠在處理複雜問題時展現更強的推理能力。目前 CoT token 會被摘要,尚未開放給 API 用戶,但隨著強化學習技術的加入,模型的連鎖思考能力將進一步提升
  • API 與使用限制
    o1-mini 在 ChatGPT Plus 用戶中設有每週 50 次提示的限制,並計劃推出更多 API 訪問層級和更高的速率限制。提示緩存是用戶的熱門需求,未來可能會加入此功能。
  • 價格、微調與擴展
    o1 的定價將遵循每 1-2 年降價的趨勢,並支持批量 API 定價。模型的微調尚無具體時間表,但研究與工程人才的限制可能會影響未來的推理擴展計劃。
  • 模型開發與研究亮點
    o1 模型在創造性思維、哲學推理及複雜任務處理上展現了強大能力,甚至內部測試中也表現出色。未來版本將進一步擴展世界領域知識,並更新數據以提升性能。
  • 提示技術與最佳實踐
    o1 模型對於提示的接受度高,尤其是在檢索增強生成(RAG)技術的輔助下,能夠進一步改善推理性能。提供相關上下文有助於提高表現,而無關的內容可能會降低其效果。
  • 未來展望
    o1-preview 正處於早期測試階段,未來將繼續優化延遲和推理時間,並大幅增強模型的創造性與推理能力。

o1-preview 模型功能實測

先說結論,真的非常的強,不論是產生程式、理解程式、修改程式,都和過去是完全不同等級的狀況!非常的厲害。

這是我今天使用o1-preview 來製作一個HTML的俄羅斯方塊的對話紀錄,可以看到ChatGPT完美的完成任務,真的是沒有BUG的完整的遊戲,而且修改的動作也都非常的完美,真的可以靠指令達到我的許多要求。我覺得這樣的程度的模型是真的會影響到許多工程師的未來性。

對話紀錄在此:https://chatgpt.com/share/66e6bcf1-4254-8005-a573-a250e1b51702

我們可以看見現在的o1-preview會有著更多細緻的思考流程,為我們將一個很大的指令拆分成許多個步驟,並重新檢視、整個整個程式碼,接著則是設置遊戲的玩法。

接著我請他增加計分板和顯示下一個方塊的功能也完美達成

請他幫忙調整版面也非常完美的完成功能

這個是成果:https://claire-chang.com/wp-content/uploads/2024/09/test.html

操作說明:

  • 使用 左箭頭鍵右箭頭鍵 控制方塊左右移動。
  • 使用 下箭頭鍵 加速方塊下落。
  • 使用 上箭頭鍵 旋轉方塊。
  • 使用空白鍵直接下降。

利用emscripten來編譯WebAssembly 

WebAssembly 是甚麼

WebAssembly(Wasm)是一種二進制格式的指令集,用於在網頁瀏覽器中高效地執行程式碼。它由 W3C 標準組織制定,目的是提供一種高性能、跨平台的執行環境,讓開發者可以在網頁上運行接近原生效能的應用程式,尤其是使用 C、C++、Rust 等語言編寫的程式碼。

以下是 WebAssembly 的主要特點:

  1. 高效能:WebAssembly 使用二進制格式,這使得程式在瀏覽器中能夠快速加載和執行,效能接近原生應用(如桌面程式)。它的運行效率遠超 JavaScript,特別適合計算密集型的應用,如遊戲、圖形處理、數學計算等。
  2. 跨平台:WebAssembly 可以在所有現代主流瀏覽器中運行(如 Chrome、Firefox、Safari 和 Edge),並且它不依賴於具體的操作系統或硬體架構,確保跨平台兼容性。無論在桌面、移動設備還是其他嵌入式設備上,只要有瀏覽器支持,Wasm 程式都可以執行。
  3. 語言無關:雖然 WebAssembly 最初是為了 C、C++ 和 Rust 這些高效能語言設計的,但理論上任何語言都可以編譯成 WebAssembly。這使得許多非 JavaScript 語言的開發者可以將他們的程式碼移植到網頁上運行。
  4. 與 JavaScript 互操作:WebAssembly 可以與 JavaScript 互相調用,讓開發者在不拋棄現有 JavaScript 代碼的情況下,把 WebAssembly 作為性能密集型任務的輔助工具。JavaScript 可以用來處理前端邏輯,而 WebAssembly 則負責複雜的數據處理或計算任務。
  5. 安全性:WebAssembly 運行在瀏覽器的沙盒環境中,這意味著它繼承了網頁應用的安全模型,無法直接訪問用戶的系統或資料,確保了安全性。

WebAssembly 是一種讓網頁能夠運行接近原生應用效能的技術,特別適合對性能要求較高的應用,同時保持了跨平台的便利性。

WebAssembly 的應用場景

  • 遊戲開發:開發者可以將原生遊戲引擎(如 Unity、Unreal)編譯成 WebAssembly,從而在瀏覽器中直接運行高效能的 3D 遊戲。
  • 視頻處理和圖像處理:如實時編碼、解碼或濾鏡應用,能夠大幅提升處理速度。
  • 數據密集型應用:如科學計算、機器學習模型運行等,能夠在網頁端完成重度計算任務。

使用Emscripten將C專案編譯為WebAssembly

Emscripten 是一個開源編譯器工具,可以將用 C 和 C++ 編寫的程式碼編譯成 WebAssembly(.wasm)或 JavaScript,使這些程式能夠在瀏覽器中運行。它的主要目的是讓開發者能夠將桌面應用程式、遊戲或其他基於 C/C++ 的軟體移植到網頁環境中。

具體來說,Emscripten 的功能有以下幾個重點:

  1. 編譯到 WebAssembly:Emscripten 可以將 C/C++ 程式編譯成 WebAssembly(Wasm),這是一種高效的二進位格式,專為瀏覽器和其他環境中的快速執行而設計。Wasm 比 JavaScript 執行效率更高,特別適合需要高性能的應用。
  2. 編譯到 JavaScript:除了 WebAssembly,Emscripten 還可以將 C/C++ 程式編譯成 asm.js,這是一種高度優化的 JavaScript 子集,主要用於在沒有 WebAssembly 支援的舊瀏覽器上運行。
  3. 跨平台支持:Emscripten 支援多種系統函式庫和 API(如 POSIX、OpenGL 等),這使得在桌面應用中常用的功能也能在網頁中運行,減少了移植工作的難度。
  4. 使用 LLVM 編譯框架:Emscripten 基於 LLVM 編譯架構,這使得它能夠將編譯過程標準化,並且能很好地支援現代 C 和 C++ 標準。

Emscripten安裝流程

下載檔案

https://github.com/msys2/msys2-installer/releases/download/2024-01-13/msys2-x86_64-20240113.exe

開啟模擬器

開啟ucrt64.exe

cd /D/Git/lbde265/

安裝所需套件

pacman -Syu
pacman -S python3 clang cmake git make autoconf automake gcc
pacman -S mingw-w64-ucrt-x86_64-nodejs
pacman -S mingw-w64-ucrt-x86_64-gcc
pacman -S mingw-w64-ucrt-x86_64-emscripten
pacman -S base-devel mingw-w64-x86_64-toolchain

安裝Emscripten

nano ~/.bashrc
export EMSDK="/D/Git/lbde265/emsdk"
export PATH="$PATH:/D/Git/lbde265/emsdk"
source ~/.bashrc

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest --permanent
source ./emsdk_env.sh

nano ~/.bashrc
export PATH="$PATH:/d/Git/lbde265/emsdk/upstream/emscripten"
export PATH="$PATH:/d/Git/lbde265/emsdk"
export PATH="$PATH:/c/msys64/ucrt64/bin"
export PATH="$PATH:/c/msys64/usr/local/bin"
export PATH="$PATH:/c/msys64/usr/bin"
export PATH="$PATH:/c/Windows/System32"
export PATH="$PATH:/c/Windows"
export PATH="$PATH:/c/Windows/System32/Wbem"
export PATH="$PATH:/c/Windows/System32/WindowsPowerShell/v1.0/"
export PATH="$PATH:/c/msys64/usr/bin/site_perl"
export PATH="$PATH:/c/msys64/usr/bin/vendor_perl"
export PATH="$PATH:/c/msys64/usr/bin/core_perl"
source ~/.bashrc

測試

emcc -v

安裝libde265.js

git clone https://github.com/strukturag/libde265.js.git
chmod +x ./configure
sh build.sh

wget https://github.com/strukturag/libde265/releases/download/v1.0.15/libde265-1.0.15.tar.gz
tar xzf libde265-1.0.15.tar.gz
cd libde265-1.0.15
./configure --disable-sse --disable-dec265 --disable-sherlock265 --enable-log-error --enable-log-info --enable-log-trace
emmake make

———->引用 gcc 或 g++ 的行。對於 Emscripten,您需要將它們替換為 emcc 或 em++。(子目錄也要改)

如果您要針對 WebAssembly 進行編譯,您需要使用 Emscripten 編譯器(emcc 或 em++)代替傳統的 gcc(C 編譯器)或 g++(C++ 編譯器)。


———->改成CFLAGS = -g -O2 -Wall

CFLAGS 是編譯時傳給 C 編譯器的選項。這裡的選項有:

  • -g:產生調試信息,便於使用調試工具。
  • -O2:啟用優化等級 2,使生成的程式碼更高效。
  • -Wall:開啟所有警告,便於識別代碼中潛在的問題。

編譯AV1的WebAssembly

https://github.com/GoogleChromeLabs/wasm-av1

原本官方的教學是使用

make

但是這樣會失敗

應該要使用

emcmake cmake ./third_party/aom -DAOM_TARGET_CPU=generic
emmake make