llama.cpp 的載入速度加速

Hacker News 上看到「Llama.cpp 30B runs with only 6GB of RAM now (github.com/ggerganov)」這個消息,原 pull request 在「Make loading weights 10-100x faster #613」這邊。

這個 PR 的作者 Justine Tunney 在 PR 上有提到他改變 model 檔案格式,以便改用 mmap(),大幅降低了需要預先讀取的時間 (因為變成 lazy-loading style),而且這也讓系統可以利用 cache page,避免了 double buffering 的問題:

This was accomplished by changing the file format so we can mmap() weights directly into memory without having to read() or copy them thereby ensuring the kernel can make its file cache pages directly accessible to our inference processes; and secondly, that the file cache pages are much less likely to get evicted (which would force loads to hit disk) because they're no longer competing with memory pages that were needlessly created by gigabytes of standard i/o.

這讓我想到在資料庫領域中,PostgreSQL 也會用 mmap() 操作,有點類似的概念。

另外 Justine Tunney 在這邊的 comment 有提到一個意外觀察到的現象,他發現實際在計算的時候用到的 model 內容意外的少:他用一個簡單的 prompt 測試,發現 20GB 的 30B model 檔案在他的 Intel 機器上實際只用到了 1.6GB 左右:

If I run 30B on my Intel machine:

[...]

As we can see, 400k page faults happen, which means only 1.6 gigabytes ((411522 * 4096) / (1024 * 1024)) of the 20 gigabyte weights file actually needed to be used.

這點他還在懷疑是不是他的修改有 bug,但目前他覺得不太像,也看不太出來:

Now, since my change is so new, it's possible my theory is wrong and this is just a bug. I don't actually understand the inner workings of LLaMA 30B well enough to know why it's sparse. Maybe we made some kind of rare mistake where llama.cpp is somehow evaluating 30B as though it were the 7B model. Anything's possible, however I don't think it's likely. I was pretty careful in writing this change, to compare the deterministic output of the LLaMA model, before and after the Git commit occurred. I haven't however actually found the time to reconcile the output of LLaMA C++ with something like PyTorch. It'd be great if someone could help with that, and possibly help us know why, from more a data science (rather than systems engineering perspective) why 30B is sparse.

如果不是 bug 的話,這其實冒出了一個很有趣的訊號,表示這些 model 是有可能再瘦身的?

Google 說要把 double quote 強制搜尋的功能加回來...

Hacker News Daily 上看到「We're improving search results when you use quotes (blog.google)」這則,才知道原來被拔掉了?(不過已經很久不是拿 Google Search 當主力了...)

原文在「How we're improving search results when you use quotes」這邊,裡面提到:

For example, if you did a search such as [“google search”], the snippet will show where that exact phrase appears:

[...]

In the past, we didn’t always do this because sometimes the quoted material appears in areas of a document that don’t lend themselves to creating helpful snippets.

在「Google for the exact phrase (and no, quotation marks don't help)」這邊可以看到 2020 的時候 double quote 就已經不是傳回精確的結果了。

不過應該不會回去用 Google Search 了,一方面是 Kagi 的表現還不錯,另外一方面是避免讓 Google 拿到更多資訊...

從三角函數 cosine 的實做問題學一些週邊知識...

前幾天在 Hacker News 上看到「Implementing Cosine in C from Scratch (2020) (austinhenley.com)」這篇 2020 的文章,原文是「Implementing cosine in C from scratch」,裡面內在講自己刻三角函數的 cosine 所遇到的一些嘗試。

cosine 是很基本的函數,所以可以使用的地方很多。另外一方面,也因為他不是那麼直覺就可以實做出來,在現代的實做裡面其實藏了超多細節...

不過真的有趣的是在翻 Hacker News 上的討論時陸陸續續翻其他的資料看到的知識。

第一個看到的是 Intel 對於 FPU-based 指令集內的 FSIN 因為 π 的精度不夠而導致誤差超大 (尤其是在 0 點附近的時候):「Intel Underestimates Error Bounds by 1.3 quintillion」,然後 AMD 是「相容」到底,所以一樣慘:「Accuracy of FSIN and other x87 trigonometric instructions on AMD processors」。

這個就是有印象,但是太久沒有提到就會忘記...

第二個是 musl libc 裡的 cosine 實做 (看註解應該是從 FreeBSD 的 libc 移植過來的?):「__cos.c\math\src」與「cos.c\math\src」(話說 cgit 在 html 內 title 的內容對路徑的表達方式頗有趣,居然是反過來放...)。

拆開的部份是先將範圍限制在 [-\pi/4, \pi/4] 後 (這個部份看起來是透過 __rem_pio2.c 處理),再丟進公式實際運算。

另外帶出來第三個知識,查資料的時候翻到 binary64 (這也是 C 語言裡面的 double) 與 binary128 的差異:

而大家很常拿來惡搞的 double double 則是利用兩個 double 存放,形式是 v = head + tail,利用不同的 exponent 表示來不同部份的值,以提高經度:

A common software technique to implement nearly quadruple precision using pairs of double-precision values is sometimes called double-double arithmetic.

不過這樣的精確度只能到 106 bits,雖然跟 binary128 能達到的 113 bits 相比低了一些,但在大多數的情況下也還算夠用:

Using pairs of IEEE double-precision values with 53-bit significands, double-double arithmetic provides operations on numbers with significands of at least[4] 2 × 53 = 106 bits (...), only slightly less precise than the 113-bit significand of IEEE binary128 quadruple precision.

Python 裡使用超過 Double Precision 的運算

Hacker News 上爬到的,是一篇 2019 的文章:「When Double Precision Is Not Enough (adambaskerville.github.io)」,原文在「T>T: When Double Precision is Not Enough」。

作者是拿矩陣 (matrix) 的運算當例子,遇到了 double precision 造成的計算誤差問題:

There is no error with the program; this discrepancy is caused by a loss of numerical accuracy in the eigenvalue calculation due to the limitation of hardware double precision (16-digit).

解法是用 mpmath 增加精度,算是一種暴力解,到要注意計算會慢很多:

Note that this library is incredibly slow for large matrices, so is best avoided for most applications.

另外在 Hacker News 的討論串裡面看到個有趣的東西:「Herbie: Automatically Improving Floating Point Accuracy」這個專案,你把公式丟進去,Herbie 會試著提供等價公式來維持精度,像是 \sqrt{x+1} - \sqrt{x} = 1 / ( \sqrt{x+1} + \sqrt{x} ) 這種東西。

半自動化幫你改善...

台美之間的租稅協定 (還在橋)

看到「因應美稅改 賴揆:加速洽簽台美租稅協定」這則消息,如果沒記錯的話,有不少服務都是美國公司出帳... (像是 AWSSlackGitHub 這類在公司裡很常用的服務)

參考「我國股利、利息及權利金扣繳率(%)一覽表」這邊的資料,應該有機會從 20% 降到 10%?也就是說實付 100 萬的金額本來要多繳 25 萬 (帳要做成 100 萬 / (1 - 0.2) = 125 萬,其中的 20% 是 25 萬萬稅,100 萬實際支付),現在只要繳 11.1 萬 (100 萬 / (1 - 0.1) = 111.1 萬)?

不過有些特殊情況本來就有更優惠的稅務方式 (像是使用國外平台提供服務 (e.g. AWS),而服務的對象也是境外使用者的情況),這些組合可以研究看看要怎麼搞...

AWS Lambda 可使用的記憶體空間從 1.5GB 變成 3GB

AWS 是說 AWS Lambda 可用的記憶體空間 double 啦,不過 3008MB 這個數字有點怪...:「AWS Lambda Doubles Maximum Memory Capacity for Lambda Functions」。

You can now allocate 3008MB of memory to your AWS Lambda functions. Previously, the maximum amount of memory available to your functions was 1536MB. Now, it's easier to process workloads with higher memory or denser compute requirements, such as big data analysis, large file processing, and statistical computations.

這個就真的全區都生效了,包括一般人不能註冊的 AWS GovCloud (US) 與中國區:

This feature is available in US East (N. Virginia), US East (Ohio), US West (N. California), US West (Oregon), AWS GovCloud (US), Canada (Central), South America (São Paulo), EU (Frankfurt), EU (Ireland), EU (London), Asia Pacific (Mumbai), Asia Pacific (Seoul), Asia Pacific (Singapore), Asia Pacific (Sydney), Asia Pacific (Tokyo), and China (Beijing).

[ 與 [[ 的差異 (Left square bracket)

在寫 shell script 時,[[[ 到底用起來有什麼不一樣?查出來記錄起來:「What is the difference between double and single square brackets in bash?」。

第一高分的答案 (由 Kyle Brandt 回答) 與第二高分的答案 (由 abhiomkar 回答) 都值得看,尤其是 abhiomkar 寫的範例很清楚:

  $ [ a < b ]
 -bash: b: No such file or directory
  $ [[ a < b ]]

對判斷式子裡面的解讀是不一樣的。

利用 Journal filesystem 與 Double write buffer 改善 InnoDB 寫入效能

Percona 的「How to improve InnoDB performance by 55% for write-bound loads」這篇在討論 Journal filesystem 以及 InnoDB 的 Double write buffer。

先講文章內的結論。

ext4 上開啟 Journal filesystem 功能後並且關掉 InnoDB 的 Double write buffer 後,資料的安全性不受影響,但效能上升非常多。而與目前常用的 XFS 比較起來也是領先不少。

要注意的是,這邊的數據是資料大小小於記憶體大小時 tpcc-mysql 的執行數據。

原文還有探討其他的狀況,像是 InnoDB 與 MyISAM 混用的問題,有用到的人應該自己去看看原文。

而目前在公司用 XFS 已經用習慣而且相當穩定,但該來花時間投資在 ext4 了,常常可以看到 ext4 很不錯之類的消息。