雷鋒網(公衆号:雷鋒網)按:本文作者覃超,前facebook軟體工程師,現為frees資本技術合夥人。
<a href="https://www.facebook.com/notes/mark-zuckerberg/building-jarvis/10154361492931634" target="_blank">zuck原貼</a>
文章頭圖是一段 jarvis 的代碼。作為一個技術流作者,我在最後的附錄解讀那段代碼:
文章開頭zuck先叙述了自己編寫jarvis的心路曆程:
這個技術架構如下:一個 jarvis server 在服務端跑,上面主要是做語言處理、語音識别和人臉識别 (zuck家的大門需要用)。
輸入端為各種家用硬體,也就是上圖中左邊那一列,依次是:
"alexa, turn on the kitchen lights"
"alexa, raise the living room lights by fifty percent"
"alexa, set the basement thermostat to 70 degrees"
黑人臉 -_- 這也能解釋為什麼在網上看到的智能家庭的視訊來來回回都是這幾個控制指令。
2. lights:燈
3. thermostat:調溫度的
4. doors:門和門禁系統
6. spotify:美國版的網易雲音樂。spotify由sean parker創立(前facebook ceo和聯合創業人之一;也就是在《社交網絡》電影裡抽大麻的那個。注意:大麻在美國一些州已經合法,另外它的成瘾性和危害都小于香煙),spotify和facebook關系很好,在2011年深度內建在facebook中。
7. cameras:攝像頭
8. toaster:
老美耿直,早餐都吃的是toast,這個機器用來加熱它,然後塗點果醬和黃油,就是一頓豐盛的早餐。
9. t-shirt cannon:t恤加農炮。很多讀者這時估計懵逼了,問:“小魔王同學,你是不是說錯了?紮克伯格沒事在家裡放一個加農炮幹嘛?” 對的,其實他的衣櫃裡安裝了一個t恤的發射器,可以直接把t恤噴射出來,打到他的手裡。
架構圖裡的右側為三個使用者系統:messenger bot、語音app和門禁攝像頭。接下來小紮說了他一步步是如何走過來的:
第一章:連接配接家裡的家具裝置。
這塊zuck坦言做這個ai家庭系統比跑365英裡的任務要稍微簡單一些(至少少費時),但是最麻煩的環節就是連接配接這些家裡的各種裝置。他甚至需要“逆向工程”一些硬體裝置的api(比如燈和音響),使得可以通過程式來控制它們。toaster換了一個1950年的硬體,另外zuck還專門給beast(zuck的狗)的喂食器以及t恤的彈射炮做了硬體的改動。
由此可見以後iot(物聯網)的重要性和前景。
第二章:自然語言處理
分為兩部分:文字消息處理和語音處理。前者處理的難度是同義詞和上下文,而後做音樂控制的時候發現播放指令的處理更加麻煩,比如:
“播放周傑倫”:這句指令在處理的時候要判斷周傑倫到底是人還是歌名;另外zuck的例子:
"play someone like you", "play someone like adele",前者是歌名,後者則是進行類似風格的歌曲推薦。zuck通過不斷訓練和加強jarvis ai,使得它現在對于zuck的歌曲喜好有記憶和認知,是以zuck一般直接說:“play me some music”。jarvis便直接開始播放,另外zuck有時心情不對的時候,想聽輕音樂,便說:“that's not light, play something light”,jarvis自己換歌曲并且學習。
第三章:視覺和面部識别
人的大腦有1/3的部分專門用來做視覺處理,包括圖像、模式識别和追蹤。zuck的房子門禁同樣也需要支援視覺和面部識别功能:
這部分在ai領域一直是發展前沿,是以有不少現成的model和開源架構。facebook之前就開放了一套api來判斷這個圖檔裡是否有你fb好友,以及将面部位置可以從圖檔中定位出來。
zuck為了做智能門禁,在大門口裝了好幾個攝像頭,為了可以更好地捕捉人臉圖檔。jarvis系統24小時不斷進行人臉探測和識别,當有人且是zuck好友的時候,給zuck發消息詢問是不是想見的人。
ai視覺還幫助jarvis做其他事情,比如看max(zuck女兒)是否睡醒,如果醒了的話,jarvis邊自動開始播放max喜歡的歌曲或者給max上中文課(從小開始學習中文 -_-)。另外借助視覺系統,可以更加有效地知道家裡的人的所在位置,這對于更好地執行有上下文的指令有巨大幫助。比如當有人說:“turn on the lights”,肯定最佳的動作是打開此人所在位置的燈。
第四章:messenger bot
老外現在喜歡用 bot,是以zuck把各種操作指令都放在手機上,具體說來是 facebook messenger 的 bot上(類似于slack的bot或者微信的一個公衆号)。于是zuck隻需要像這個公衆号發消息即可。如下圖:
zuck介紹用 messenger bot 開發的各種便利之處,它比起做一個app來更輕,更容易跨平台,同時也不同處理push、啟動、注冊等一系列繁瑣routine的事情。平時zuck可以通過發文字或者語音消息(原文:audio clip,這個功能是小魔王我當年親手做的~ :d),然後jarvis ai将其發送到server上, 進而開始做文字或者語音處理,提煉出需要執行的指令來操作zuck家。同時jarvis ai還會主動發消息給zuck,比如有人在門口時,jarvis會把照片和識别出的人的資訊發給zuck,讓他确認是否是自己要見的人。
zuck自己沒有料想到的是:平時和jarvis的交流大部分都是通過文字資訊;雖然開始zuck以為自己會是說話為主,但是後來發現text更加友善更加能保護個人隐私,不打擾别人。這從一個側面也能反應出來 voice message 在北美的messenger流行不起來的一個重要原因:随着社會進步,人會越來越重視隐私或是變得有些緘默。zuck還透露不管是fb messenger還是whatsapp上也看出類似的趨勢:文本資訊的消息數量遠比語音消息增長得快。這裡給做ai的各位公司一個啟示:雖然現在語音識别仿佛是标配,但是ai系統可能更加需要注意在文本處理上的成熟度,因為人們會大量使用文本控制而不是之前設想的語音控制。雖然後者讓pm或者ceo覺得好像是更便捷更cool的人機互動方式。
第五章:語音處理
zuck當然也做了語音識别的子產品來輔助控制 jarvis:
zuck說之前開發ios還是在2012年,現在再次開發,他感受到整個ios和fb的toolchain的改進巨大,語言和xcode的增強使得程式設計和做app的門檻大大降低。
通過開發和使用這個voice app,zuck對于ai和語音識别在産品上的思考:
語音識别的算法在上下文和聯想方面需要加強得還不少;類比人類進行語音識别的時候,不僅在聽你目前說什麼并記下來,同時要時刻在預測你接下來準備說什麼,大腦表現得非常自然而且高效。而計算機,即使最近開始使用rnn(recurrent neurol network)好了不少,但是依然有很大的提升空間;
語音識别現在在了解人類的支離片語上表現不佳,另外對于正常情況下使用的語音識别能力比較弱。大部分的系統都在做特别功能範圍(比如google search, amazon echo)内的語音識别。
語音的加入讓産品和人之間更加有情感交流,zuck覺得這肯定是以後産品發展的方向。能用語音進行交流之後,zuck自己越用越覺得有意思,然後開始改進jarvis,讓其變得更加幽默有趣。還加入了一些遊戲和黑話給jarvis。
語音的識别和運用方面,zuck認為可以做的創業才剛剛開始。(是以各位抓住機會!)
第六章:facebook的工程師環境
這一段,zuck說自己雖然是ceo,但是從未停止過coding,但主要以個人項目為主。通過這次開發 jarvis,zuck又重新體會了一次整個fb的技術環境的魅力,就類似于一個新入職的工程師一樣走完了整個bootcamp的過程。他說不僅上手實踐ai和了解了最新ai方面的進展,同時意外收獲了很多關于開發技術方面的知識。zuck贊賞fb的代碼非常有條不絮,另外在開源上做得很好,甚至zuck在文章裡親自列舉出 jarvis上使用的開源架構:
最後zuck歡迎開發者都來使用下這些開源庫,來感受下ai最新發展的魅力。另外他一直堅持内部工具和技術的基礎設施對于一個網際網路公司的重要性,是以最後他說:“building internal tools that make engineering more efficient is important to any technology company, but this is something we take especially seriously. so i want to give a shout out to everyone on our infra and tools teams that make this so good.” 是以這裡可以看出,矽谷公司把技術部門真真切切地當做是公司的重要資産,去鼓勵去培養;而國内很多公司對于技術團隊,更多當成是一種工具,甚至是開支部門。是以各位想單純醉心于技術鑽研的人,早點去矽谷是一條最好的出路。
第七章:下一步
zuck的文章到了這裡,已經進行到了尾聲。zuck說雖然2016年的挑戰已經結束,但是對于jarvis的開發和優化會繼續。具體需要做:
開發android下的語音識别app
接入更多的室内硬體和更多的應用
讓jarvis擁有學習能力。zuck原話:“if i spent another year on this challenge, i'd focus more on learning how learning works.” 即希望教會jarvis如何學習,或者說得更加酷炫:讓jarvis學習如何學習。(小魔王補充:chunk it up,deliberate practicing,feedbacks,10000 hours theory!)
最後zuck準備再抽象一層自己的代碼,然後在明年将其開源(接受小魔王覃超的進一步code review :-d)
第八章:結論
關于結論這部分,zuck原文相當得精煉且有意義,我實在覺得應該把英文貼上來,各位都能閱讀一下:
“building jarvis was an interesting intellectual challenge, and it gave me direct experience building ai tools in areas that are important for our future.
i've previously predicted that within 5-10 years we'll have ai systems that are more accurate than people for each of our senses -- vision, hearing, touch, etc, as well as things like language. it's impressive how powerful the state of the art for these tools is becoming, and this year makes me more confident in my prediction.
at the same time, we are still far off from understanding how learning works. everything i did this year -- natural language, face recognition, speech recognition and so on -- are all variants of the same fundamental pattern recognition techniques. we know how to show a computer many examples of something so it can recognize it accurately, but we still do not know how to take an idea from one domain and apply it to something completely different.
to put that in perspective, i spent about 100 hours building jarvis this year, and now i have a pretty good system that understands me and can do lots of things. but even if i spent 1,000 more hours, i probably wouldn't be able to build a system that could learn completely new skills on its own -- unless i made some fundamental breakthrough in the state of ai along the way.
in a way, ai is both closer and farther off than we imagine. ai is closer to being able to do more powerful things than most people expect -- driving cars, curing diseases, discovering planets, understanding media. those will each have a great impact on the world, but we're still figuring out what real intelligence is.
overall, this was a great challenge. these challenges have a way of teaching me more than i expected at the beginning. this year i thought i'd learn about ai, and i also learned about home automation and facebook's internal technology too. that's what's so interesting about these challenges. thanks for following along with this challenge and i'm looking forward to sharing next year's challenge in a few weeks.”
這裡可以看出zuck的執行力以及實踐能力。一方面通過寫jarvis來親自學習了一下ai現在的最近進展,另一方面這種第一手經驗很好地回報回來讓他更加有信心來判斷以後5-10年ai和相關産品的發展方向。我覺得我自己以及中國的廣大創業者特别是投資人都應該學習這種實幹的态度,而不是停留在嘴皮上預測未來。
zuck認為計算機智能在某些領域做得已經很好,但是最關鍵的“自學能力”和“舉一反三”能力幾乎沒有(原文:we know how to show a computer many examples of something so it can recognize it accurately, but we still do not know how to take an idea from one domain and apply it to something completely different.)。zuck自己話了100個小時來做jarvis,但是他認為就算花1000個小時,也無法讓機器能夠有自學能力,除非在人工智能領域可以有學術、科學上的重大突破。
從demo視訊裡來看的話,很多時候jarvis感覺并不好用。但是畢竟能夠用messenger+聲音來控制自己的家庭裝置是一件非常酷炫的事情。
---- 附帶圖檔中代碼的解讀 ----
這段代碼是用php外加facebook的fbt寫就,總體邏輯:将異步task設定好(其中一個task就是做圖檔的人臉識别),另外從ai api中取得并設定好config,最後調用接口并且等待結果。
其中代碼細節:
從代碼邏輯來看,這應該是jarvis的源代碼。從代碼細節看,作者的水準還行,但也不夠完美。可以看出邏輯清晰但是代碼功力不太夠 -_-。 這也合情合理,畢竟zuck沒時間保持一個高頻次寫代碼的狀态,是以肯定是“三天不寫手生”。舉例來說(如果嚴格的code review的話;哈哈!給zuck做code review真是三生有幸!):
最開始兩行:$task這個變量不需要,直接往 "image" => ... 這裡灌即可;而且 $task 這個太泛的名字也沒有具體含義。要不就改成:$face_detect_task,當然最好就直接放入map裡算了。
這兩句寫得一般,看起來有點學生時代寫大作業的代碼的風格;同名變量反複使用,另外對于null的檢查不對稱。
看到這段代碼,我想很多程式員會哭笑不得。首先代碼邏輯有點hacky,初步判斷應該是 jarvis_facerec 沒來得及完成。。。是以趕鴨子上架暫時用 rc_model 來頂上;畢竟馬上就christmas和新年了,zuck沒做完也要先趕在deadline之前釋出嘛。注意!我覺得這個态度和做事方式才是對的, 不要拖,也不要等到完美的時候才釋出,因為一個項目一個作業永遠都無法達到你想要的完美狀态。正如zuck自己之前在facebook裡強調:“done is better than perfect!”
idx是一個helper method,其實就等于 $api_config['detection_tier'],但是用idx的好處是如果 $api_config 為空,那麼 idx 不會崩潰,而是傳回null,而 $api_config['detection_tier'] 直接觸發異常。是以這裡回頭看,zuck的80行寫得并不好,最好寫成:$api_config = idx(api_config, 'facer'); 對了,idx還可以支援第三個參數,就是預設值;如果這個key在map中沒有的話,就直接傳回預設值。
這句是技術含量最高的一句。facedetectrequestconfig::gen,這裡gen代表generator,由于曆史原因,facebook的代碼用的是generator,是以異步操作就起名gen;但是這裡用的是新的 resumable function;也就是 ::gen 傳回一個 awaitable object(類似promise,如果你玩js或者其他語言),然後前面的await就将異步操作出發執行,最後得到從 detection_tier 來的 config。具體關于 async & await,以及 resumable function 可以參考:http://meetingcpp.com/index.php/br/items/resumable-functions-async-and-await.html (這裡php中的resumable function是facebook自己做的文法加強;c#裡一直就有,而c++會在下一代的c++1y裡引入 resumable function)。
print "configured...\n" 這句話太萌,典型的學生項目代碼。
類似于: console.log(xxx) 或者 system.out.println("configured...) 或 nslog(@"configured..."); 要是公司項目的代碼這麼寫,估計要被tech lead直接罵死。
不過這裡zuck敢于自己動手開始寫代碼,并且最後可以有一個prototype上線開始能夠使用,已經非常厲害了(畢竟很多ceo一天到晚忙除了開會,幾乎什麼都做不了)。
最後zuck那段代碼的最佳形态是:
本文作者:覃超