Tensorflow V2.0 相容性小實驗

為了一圓 AI 大夢, 我買了一塊 GTX 3090. 原本在 PCHOME 觀望三分鐘, 嫌貴沒按下去, 後來就再也買不到了!!!  電腦的東西不是應該慢慢降價嗎? “早買早享受, 晚買享折扣" 是大家都知道的定律啊!? 不過這次不一樣, 顯卡價錢還一天比一天高. 最後只好破釜沉舟買了蝦皮最後一張現貨, 而且是散熱貼片品質不好的技嘉. 

卡片到手之後, 先找個 BenchMark 來燒機, 結果老舊的 i7 扯了後腿, 分數還差正常的 3090 一成. 腦筋一賺, 來挖礦吧! 結果以前會動的 guiminer 程式都連不上礦池. 上網一查才知道電腦已經不能挖比特幣了. 不死心的我研究了一下, 得知可以在 Nicehash 挖別的幣換比特幣, 這樣果然就行了. 但是算力全開的話, VRM 瞬間就飆到 110 度. 嚇得死人了. 只敢開溫和模式當背景程式跑.

好了, 言歸正傳. 算 AI 會不會燒 VRM 要試了才知道.  然而, 客戶的事情如雪片般飛來, 我始終不能定下心跑程式. 兩個月過去, 比特幣都挖了 0.005 顆了, 但是正事還沒開工. 好不容易有清明連假, 趕快把電腦環境安裝起來. 有一篇文章跟我以前的軌跡很相似 [1], 於是我就按照這個思路來恢復環境.

不過 Google 排名靠前 – 很多人引用的文章相對都是比較舊的. 前述文章中的 Cuda 9 已經該進版到 Cuda 11.2, Cudnn 由 7.5 進版到 8.1.1, 其他流程都差不多. 按照文章一路破關, 然後在測試環境這邊卡住了. 當我執行 c = tf.matmul(a, b) 會得到:

" failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED"

根據 [2] 所述, 這是分配記憶體的問題. 按照官網 [3] 要下tf.config.experimental.set_visible_devices.

但這個還是只能治標, 不能治本. 晚點還是會遇到

tensorflow.python.framework.errors_impl.InternalError: Blas xGEMM launch failed : a.shape=[1,2,3], b.shape=[1,3,2], m=2, n=2, k=3 [Op:MatMul]

看起來正確解答是這三行 [4]:

import tensorflow as tf
physical_devices = tf.config.list_physical_devices('GPU') 
tf.config.experimental.set_memory_growth(physical_devices[0], True)

但是要在 init 的時候下, 不能臨時抱佛腳. 所以要重來一次.

然後在 tensorflow 2.0, 過去的 tf.Session() 也被淘汰了, 要改用 f.compat.v1.Session(). tf.ConfigProto 也換成  tf.compat.v1.ConfigProto (待確認). 比較嚴重的區別是 tensorflow 2.0 預設開 eager execution. 會遇到

RuntimeError: The Session graph is empty. Add operations to the graph before calling run()

所以有三個方法:

A. 直接設定跟舊版相容 [7]:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

B. 或是關掉 eager execution [6]:

tf.compat.v1.disable_eager_execution()

C. 或者先宣告 session, 而不是等要用的時候才宣告. 例如 [6]:

 # Launch the graph in a session.
 with tf.compat.v1.Session() as ses:

     # Build a graph.
     a = tf.constant(5.0)
     b = tf.constant(6.0)
     c = a * b

     # Evaluate the tensor `c`.
     print(ses.run(c))

重來一次完整的步驟就是. 從 Anaconda 打開 Python 的 terminal.

import tensorflow as tf

physical_devices = tf.config.list_physical_devices('GPU') 
tf.config.experimental.set_memory_growth(physical_devices[0], True)
tf.compat.v1.disable_eager_execution()
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(log_device_placement=True))
print(sess.run(c))

 

[REF]

  1. https://ithelp.ithome.com.tw/articles/10237846
  2. https://www.itread01.com/content/1545441880.html
  3. https://www.tensorflow.org/guide/gpu
  4. ://stackoverflow.com/questions/43990046/tensorflow-blas-gemm-launch-failed
  5. https://stackoverflow.com/questions/55142951/tensorflow-2-0-attributeerror-module-tensorflow-has-no-attribute-session
  6. https://github.com/OlafenwaMoses/ImageAI/issues/400
  7. https://github.com/tensorflow/tensorflow/issues/25446

 

 

AOP 小註解

此處 AOP 指 acoustics overload point, 是指麥克風可以收到的最大聲音. 大廠開的規格大約要求 AOP 在 120~130 分貝這個水準.

有人可能舉一反二, 問到最小聲可以量到多少有定義嗎? 這個值叫做 EIN (equivalent inout noise), 在 EIN 到 AOP 之間就是 dynamic range [1].

AOP_EIN-768x887

上圖可以看到 input 的分貝數 (dB) 後面寫了 SPL, output 又寫了 dBV, 這是什麼意思呢? SPL (sound pressure level) 顧名思義是聲壓的單位 [2]. 基準點是 P0.  

p0 = 20 μPa = × 10−5 Pa 

而這個 Pa 就是大氣壓力的巴 (Pa or Pascal), 一巴等於每平方米一牛頓[3], 大氣壓力是 101.325 kPa. 而基本聲壓 P0 只有 20 μPa, 可以想像這是一個很小的壓力.

SPL = Lp = 20 log10(P/P0)

這意思是說, 光是喊得很大聲沒用, 也要考量距離多遠. 比一個鞭炮在耳朵裡爆炸更大聲的是兩個鞭炮, 而不是遠處的雷聲. 現在統一用 dB SPL 來換算, 就可以得到公平的比較標準.

接著麥克風要把聲壓換成電壓來輸出, 我們才知道相對的大小聲. 這個輸出值就改用 dBV 來衡量 [4]. 這邊 V0 的基礎就是 1 伏特 (volt). 1 Volt 就是 0 dBV. 在一塊電路板上, 1 Volt 就是很大的值, 因此喊一聲的 dBV 都是負值.

例如圖中有一個 reference SPL = 94 dB SPL, 它換算的輸出電壓就是 -38 dBV. 這個輸出也稱之為 sensitivity. 根據 [1], The sensitivity of a microphone is the electrical response at its output to a given standard acoustic input.

Sensitivity 對應到 EIN 所對應的 dBV 中間的差異就是 SNR (signal to noise ratio).

[REF]

  1. https://www.invensense.com/wp-content/uploads/2015/02/AN-1112-v1.1.pdf
  2. http://www.sengpielaudio.com/TableOfSoundPressureLevels.htm
  3. https://zh.wikipedia.org/wiki/%E5%B8%95%E6%96%AF%E5%8D%A1
  4. http://www.sengpielaudio.com/calculator-db-volt.htm

2019 年終投資回顧

2019 年即將要結束了. 除非最後十天大崩盤, 否則我只要更新最後的數字就可以確保整篇的正確性, 不至於影響我的結論才對. 當然也不排除烏鴉嘴或是莫非定律的出現, 希望不要啦!

今年是投資豐收的一年, 但老實說主要是全球股市補回去年底殺尾盤的那一波跌幅, 若以連續兩年來看, 平均起來才是比較正常的幅度. 我們看一下大家的 Google S&P500 就會跑出來的一張圖. 去年這個時候是一個大波谷, 因此從去年底往 2019年看,  真是好得不得了! 不過放長遠來看, 不過是回到上升軌道而已.

不只美國是這樣, 和美國息息相關的台灣也不過是反應慢了一點. 同樣在去年年底見到低點,  讓投資人第三季的喜悅掉進了冰箱. 

既然今年台股大漲, 我就趁亂把去年因流動性不夠, 賣不掉的永記 (1726) 給賣光了. 我個人很感謝 “虹牌油漆" 贊助我們許多體育活動, 但此股最近只剩殖利率這個優點有價值. 把它賣掉以後, 我對台股就幾乎空手了, 這樣我比較不用分神.

目前台股我只剩下兩張股票和一些零股. 瑞昱 (2379) 這一張是為了顯得合群而買的, 不然每年助理或是同事好心要幫我領股東會紀念品時, 我若回答我沒瑞昱, 這樣有點丟臉. 另外一張是國泰金乙種特別股 (2882B), 這是為了學習特別股是什麼而買的, 至今也還獲利就沒賣.

最後, 與台灣 “習習" 相關的陸股, 低點也是在與台股差不多的位置. 這線型趨勢撲朔迷離的陸股, 即使大家的微積分不好, 也能從下圖分辨得出來, 只要 hold 住一整年就有不錯的獲利!

對我們小投資人來說, 所投資的主要標的 – 美國 ETF 和大陸 ETF 都漲的情況下, 荷包當然也充實了不少, 別人都擔心崩盤, 但我覺得還好, 反正我判斷高點低點的能力趨近於 0, 還不如 buy and hold 就好. 聯電 (2303) 今年大漲約五成, 原因是大陸去美國化, 不繼續用 TI 低階製程生產的零組件, 用台積電生產也不划算, 因此就肥了比較不長進的聯電. 這麼簡單的邏輯, 您想得到嗎? 我想不到. 因此我不預測大盤. 只有好公司遇到倒楣事才會吸引我.

今年最令我討厭的就是匯損了! 買這麼多海外的標的, 當然不可能不考慮匯率. 去年年底台幣對美元是 1:30.295, 前天 (2019/12/20) 來到 1:29.75, 總共漲了 1.8% 左右. 震盪比較激烈的幾個單日, 像是 2019/10/14 國慶連休期間, 國際匯市沒放假, 因此一收假台幣大漲就 0.69%. 最近一次在 2019/12/13, 台幣單日狂升 0.683%. 台幣漲就是美金跌、港幣跌 (我買的大陸 ETF 是港幣計價).  想想一早起床什麼壞事都還沒做, 打開手機就看到幾個月的薪水蒸發, 真叫人情何以堪啊?! 

個人認為, 保有一些現金是必要的, 在台幣漲美元跌的過程中, 若手上有 “多餘" 比重的美金定存或現金, 可以考慮在美元下跌的趨勢中, 直接買美元計價的商品. 因為這陣子美金雖然一路跌, 但美股卻漲得更多. 所以花掉美元也是一種保值的方法. 理論上選擇美元與美元計價商品的雙重最低點把美元花掉是最佳解. 例如美金已經跌到某個穩定低點了, 找個美金計價的 ETF 市場 (例如某國, 某產業) 來買應該是對的.

至於已經買下去, 變成美元計價資產後, 繼續遇到美元下跌就沒轍了.  我在網路上找到一篇文章 [1],  雖然這篇文章沒有辦法能讓我們輕易避免匯損, 但它有統計圖表, 顯示不同狀況下的損失各會有多少? 

講了半天, 最後來給點數字. 以個人總資產而言, 2019 年底比 2018 年底成長 24.5% 24.72% (2020/1/1 修正). 其中有 3.76% 是薪資所得 (包括年終獎金/員工分紅等稅後轉投資) 貢獻的, 因此純投資成長約 20.74% 20.96% (2020/1/1 修正). 這 3.76% 是我贏過華倫老師的地方, 因為我還有工作, 華倫老師辭職了. 我這部分主動收入有助於拉近我和他的差距, 不然績效就輸太多了, 哈!

再以各個市場來看, 我在中國相關市場 (03169.HK, 02801.HK) 沒有新增投資, 畢竟川普打中國這麼用力, 讓我有點怕怕的, 這部分 “只"成長 16.83%. 美股的部分, 因為我把台股給賣了新增投資, 連同股價的漲幅和配息, 幾乎快成長一倍. 今年多買了 NOBL, VPU, 以及增持 KO. 原本的 BRK.B, VDC, VIG 都沒有買賣, 只是領息.

比較值得一提的是增持 KO 這件事: 中美貿易戰開打後, 大家好像突然不看好可口可樂在大陸的銷量? 某天我在臨睡前, 心血來潮打開 APP 一看, 天啊, 可樂竟然一天能暴跌 5 塊! 於是就把帳上的現金全梭了. 以我習慣的市價減到 x.9 元字尾下買單, 然後去睡覺. 第二天起床後一檢查… , 看到"全部成交" 反倒有點懊惱, 這一定是買貴了. 雖然沒買到當天最低點, 但至少買到波段最低那附近. 近來可樂終究還了我公道, 慢慢漲回 50 元大關, ㄟ..在我截這張圖的當下已超過 55 元了.

今年股市收獲不錯, 已僥倖超過上班的貢獻. 但上班是穩定的收入, 不上班容易老年癡呆和早死 [2].  雖然上班會降低我的修養, 升高我的血壓, 但為了不變成失智老人, 支付一家大小生活, 並且能有閒錢可以任性吃好一點, 這班還是要上的. 說到吃好一點的原則, 交大的饕爺燒臘雖不是學弟妹首選 [3], 但遷到螃蟹公司團膳後卻非常紅火, 不輕易排得到! 看來在交大吃得比較好, 哈!

Note, 剛剛在 Facebook 看到李忠孝大轉貼的文章 [4], 它說明了為何股市會一直上漲, 但不參與股市、房地產、債市的人辛苦工作卻被拋在後面.

[REF]

  1. https://www.yaoyuting.com/2018/10/etf_9.html
  2. https://www.cw.com.tw/article/article.action?id=5087100
  3. https://www.ptt.cc/bbs/NCTU_TALK/M.1575005672.A.0E8.html
  4. https://baike.baidu.com/tashuo/browse/content?id=013e9d86632092966d2a1a7f&fbclid=IwAR1TpbFFaG6ON9msZ9Uwvf_hU9cf4TTfia-SXPiIOUhZHDJkFYdzAyaWRLE

Multicast ABR 小註解

這個 keyword 裡面有兩個單詞, 一個是 multicast (相對於 unicast), 一個是 ABR (adaptive bit rate). 有時簡稱 M-ABR, 是個用來解決網路播放問題的技術.

網路播放怕甚麼呢? 怕大家都看不同節目, 結果頻寬爆掉. 我們可以把這種況狀視為用戶和電視業者中間的一個 unicast. 看到這裡, 聰明的網友可能已經想到, “我們用 multicast 嘛, 千千萬萬用戶只不過看那兩三百台, 我們先把節目弄到中繼站, 每個中繼站都 multicast 給看這台的那群客戶不就好了, 哇哈哈, 我好聰明…" 嗯, 這第一層的想法沒錯.

第二層想法在於客戶家裡的裝置, 必須能夠像 unitcast 一樣自由地操作, 不能說別家看到影片的幾分幾秒? 我就跟著要看幾分幾秒吧! 對

參考來自 [1] 的圖示, 我們看到影片的來源主要是直播 (live content) 或是點播 (VOD) 兩種, VOD 訴求高畫質, live 訴求低延遲. 如果一群觀眾都在看直播 – 例如直播棒球賽好了, 那大家的進度都是一樣的沒錯. 但看電影就不能強求只能看 multicast 了.

因此 M-ABR 的第一個訴求就是降低頻寬, 第二個訴求是使用者不會察覺改變.

  • REQ1 – Decrease network usage from ABR content consumption;
  • REQ2 – Keep the ABR client devices unchanged

最簡單的方法, 就是在客戶開始操作 time shift 的時候, 把 live 的 multicast 改為 unicast. 怎麼辦到呢? 這需要在網路中加上一些新的設備, 前面提到的  Multicast server 以及 Multicast to unicast proxy.

  • Multicast Server – Has 2 main purposes: creating a carrousel with the ABR segments, on a technology similar to DSM-CC (although there’s no repetition of packets) and the retransmission of missing multicast packets.
  • Multicast to unicast proxy – This is a home gateway software module, which converts multicast content into ABR segments.

到目前為止, 問題好像都迎刃而解了. 但事實上又不然. 當電視觀眾心血來潮想要倒轉回去看上一局的滿壘三振的時候, multicast server 早就把封包丟出來了, 所謂 proxy 裡面也是空空的, 必須要回到頭端去要 10 秒鐘前的那個碼流.

何況這個 multicast to unicast proxy 總要一點時間比對那幾家的封包需要轉成 unicast 吧! 還有網路總是會掉封包, 假如電視供應商到機上盒中間都不掉包 (透過 DOCSIS), 機上盒到每台電視的網路總是要掉. 整體而言 IPTV 一定會因為掉封包而比 cable TV 有更大的延遲. 在看點播的時候比較不影響, 看球賽直播時, 不免會有隔壁已經放鞭炮, 我家打者還沒揮棒的窘境.

雪上加霜的是, 電視使用者逐漸轉去看網路, 因此每個 note (想像成上述 server/proxy) 對應到的觀眾減少了, 但為滿足客戶需求, 電視頻道變多了. 這表示客戶選到同一台的命中率愈來愈低, 或者說轉成 multicast 的效益愈來愈小.天生的延遲、加上成本效益愈來愈低, 讓這個規格看起來沒啥用.

話雖如此, 還是有人在用這個規格, 那就是 Comcast. 因為 “It only makes sense on legacy cable networks. [1]" 在傳統的 cable TV 上, 前述的延遲比較小, cable 的頻寬又很大 (GPON 給 64 家分, 每家可得 38 Mbps), 這公司又是老字號 S&P500 強, 客戶群夠大, 每個 node 命中率也比較高. 但對於新業者來說, 這篇 reference 的作者就不建議.

[Ref]

  1. https://technedigitale.com/archives/1181

Emulator 小註解

根據 WIKI, Emulator 分為 hardware [1], software [2] 兩種. Hardware Emulator 是用 hardware 去模擬 IC 硬體, software emulator 則是用軟體去模擬 IC. 後者比較單純, 以我用過的 Analogic Device 的 DSP emulator, 只要設定 SRAM 的 delay cycle, 就可以知道自己寫的程式在 IC 能否跑得動.

而在 WIKI 的定義中,  ICE (In Circuit Emulator) 算 HW emulator, 但 FPGA (Field Programmable Gate Arrays) proto-typing 不算 HW emulator. 問題不出在 FPGA 不能當 HW Emulator, 而是出在 FPGA proto-typing 和 HW Emulator 有差距.

知乎這篇 [3] 說到, FPGA proto-typing 和 HW Emulator 的本質不同

  1. HW Emulator 可以處理的 gate 數較大, 即使要驗的電路變複雜, 也不像 FPGA 那樣 routing 愈複雜就跑得愈慢.
  2. HW Emulator 是由 CAD 提供一整套系統. 而 FPGA 買回來之後通常是 HW SD 做一張板子, IC designer 提供特製的 RTL 跑出來的 bitfile 檔. 為了配合 FPGA 的先天限制, 連 IC 的功能都不會完整放上 FPGA. 例如實際上跑 4 核 CPU, FPGA 上只放一核.
  3. “emulator可认为是软件simulator的硬件化,是虚拟世界;FPGA prototype是物理芯片流片前的原型化,是真实世界。" 這句話直接引用 [3]. 雖然兩者的 clock 都不夠真實, 但 emulator 下所有 IP 的 clock 能維持相對比例, 例如 CPU 可以模擬 1.5GHz, 並切搭配跑 700MHz 的 GPU. 但 FPGA 上的 CPU 就是和其它 IP 一樣都跑 MHz 等級.

三大 CAD 公司都有 Emulator 的產品, Cadence Palladium, Synopsys ZeBu, Mentor Veloce. 有趣的是,  Palladium 用特製的 processor 來實現, Veloce 用 ASIC 來實現, 而 Zebu 就是用 Xilinx 的 FPGA 來實現. 難怪 HW SD 會說: “你就把它想像成一個超大的 FPGA."

Emulator 還有不同的操作模式:

  1. Stand-alone: 全部電路在 emulator 中單獨跑.
  2. ICE: 待測電路放在 emulator, 透過  speed bridge 接到高速週邊 USB 等等.
  3. Co-simulation: 和 server 上的 sw simulator co-sim. 例如模擬 Android 跑在 IC 上就有可能用到.

先筆記到這裡.

[Ref]

  1. https://en.wikipedia.org/wiki/Hardware_emulation
  2. https://en.wikipedia.org/wiki/Emulator
  3. https://www.zhihu.com/question/47732296