快速掌握用python寫並行程序,乾貨滿滿

2021-12-31 python

目錄

2.2 改用GPU處理計算密集型程序

三、用python寫並行程序

四、multiprocessing實戰

小子今天想來談談「並行計算」,作為一個非科班人員,我為什麼去搗鼓這麼一個在科班裡也比較專業的問題了。這就要說下我前幾天做的一個作業了,當時我用python寫了個程序,結果運行了一天,這個速度可讓我愁了,我還怎麼優化,怎麼交作業啊。於是小子就去各大論壇尋丹問藥了,終於讓我發現可以用並行計算來最大化壓榨電腦的CPU,提升計算效率,而且python裡有multiprocessing這個庫可以提供並行計算接口,於是小子花1天時間改進程序,終於在規定時間內做出了自己滿意的結果,上交了作業。之後,小子對並行計算充滿了興趣,於是又重新在Google上遊歷了一番,大致弄清了GPU、CPU、進程、線程、並行計算、分布式計算等概念,也把python的multiprocessing耍了一遍,現在小子也算略有心得了,所以來此立碑,以示後來遊客。

小子本文分為四部分,一是大數據時代現狀,其二是面對挑戰的方法,然後是用python寫並行程序,最後是multiprocessing實戰。

一、大數據時代的現狀

當前我們正處於大數據時代,每天我們會通過手機、電腦等設備不斷的將自己的數據傳到網際網路上。據統計,YouTube上每分鐘就會增加500多小時的視頻,面對如此海量的數據,如何高效的存儲與處理它們就成了當前最大的挑戰。

但在這個對硬體要求越來越高的時代,CPU卻似乎並不這麼給力了。自2013年以來,處理器頻率的增長速度逐漸放緩了,目前CPU的頻率主要分布在3~4GHz。這個也是可以理解的,畢竟摩爾定律都生效了50年了,如果它老人家還如此給力,那我們以後就只要靜等處理器頻率提升,什麼計算問題在未來那都不是話下了。實際上CPU與頻率是於能耗密切相關的,我們之前可以通過加電壓來提升頻率,但當能耗太大,散熱問題就無法解決了,所以頻率就逐漸穩定下來了,而Intel與AMD等大製造商也將目標轉向了多核晶片,目前普通桌面PC也達到了4~8核。

二、面對挑戰的方法

咱們有了多核CPU,以及大量計算設備,那我們怎麼來用它們應對大數據時代的挑戰了。那就要提到下面的方法了。

2.1 並行計算

並行(parallelism)是指程序運行時的狀態,如果在同時刻有多個「工作單位」運行,則所運行的程序處於並行狀態。圖一是並行程序的示例,開始並行後,程序從主線程分出許多小的線程並同步執行,此時每個線程在各個獨立的CPU進行運行,在所有線程都運行完成之後,它們會重新合併為主線程,而運行結果也會進行合併,並交給主線程繼續處理。

圖一、多線程並行

圖二是一個多線程的任務(沿線為線程時間),但它不是並行任務。這是因為task1與task2總是不在同一時刻執行,這個情況下單核CPU完全可以同時執行task1與task2。方法是在task1不執行的時候立即將CPU資源給task2用,task2空閒的時候CPU給task1用,這樣通過時間窗調整任務,即可實現多線程程序,但task1與task2並沒有同時執行過,所以不能稱為並行。我們可以稱它為並發(concurrency)程序,這個程序一定意義上提升了單個CPU的使用率,所以效率也相對較高。

圖二、多線程並發

並行編程模型:

數據並行(Data Parallel)模型:將相同的操作同時作用於不同數據,只需要簡單地指明執行什麼並行操作以及並行操作對象。該模型反映在圖一中即是,並行同時在主線程中拿取數據進行處理,併線程執行相同的操作,然後計算完成後合併結果。各個並行線程在執行時互不幹擾。

消息傳遞(Message Passing)模型:各個並行執行部分之間傳遞消息,相互通訊。消息傳遞模型的並行線程在執行時會傳遞數據,可能一個線程運行到一半的時候,它所佔用的數據或處理結果就要交給另一個線程處理,這樣,在設計並行程序時會給我們帶來一定麻煩。該模型一般是分布式內存並行計算機所採用方法,但是也可以適用於共享式內存的並行計算機。

什麼時候用並行計算:

多核CPU——計算密集型任務。儘量使用並行計算,可以提高任務執行效率。計算密集型任務會持續地將CPU佔滿,此時有越多CPU來分擔任務,計算速度就會越快,這種情況才是並行程序的用武之地。

單核CPU——計算密集型任務。此時的任務已經把CPU資源100%消耗了,就沒必要使用並行計算,畢竟硬體障礙擺在那裡。

單核CPU——I/O密集型任務。I/O密集型任務在任務執行時需要經常調用磁碟、屏幕、鍵盤等外設,由於調用外設時CPU會空閒,所以CPU的利用率並不高,此時使用多線程程序,只是便於人機互動。計算效率提升不大。

多核CPU——I/O密集型任務。同單核CPU——I/O密集型任務。

2.2 改用GPU處理計算密集型程序

GPU即圖形處理器核心(Graphics Processing Unit),它是顯卡的心臟,顯卡上還有顯存,GPU與顯存類似與CPU與內存。

GPU與CPU有不同的設計目標,CPU需要處理所有的計算指令,所以它的單元設計得相當複雜;而GPU主要為了圖形「渲染」而設計,渲染即進行數據的列處理,所以GPU天生就會為了更快速地執行複雜算術運算和幾何運算的。

GPU相比與CPU有如下優勢:

強大的浮點數計算速度。

大量的計算核心,可以進行大型並行計算。一個普通的GPU也有數千個計算核心。

強大的數據吞吐量,GPU的吞吐量是CPU的數十倍,這意味著GPU有適合的處理大數據。

GPU目前在處理深度學習上用得十分多,英偉達(NVIDIA)目前也花大精力去開發適合深度學習的GPU。現在上百層的神經網絡已經很常見了,面對如此龐大的計算量,CPU可能需要運算幾天,而GPU卻可以在幾小時內算完,這個差距已經足夠別人比我們多打幾個比賽,多發幾篇論文了。

3.3 分布式計算

說到分布式計算,我們就先說下下Google的3篇論文,原文可以直接點連結去下載:

GFS(The Google File System) :解決數據存儲的問題。採用N多臺廉價的電腦,使用冗餘的方式,來取得讀寫速度與數據安全並存的結果。

MapReduce(Simplified Data Processing on Large Clusters) :函數式編程,把所有的操作都分成兩類,map與reduce,map用來將數據分成多份,分開處理,reduce將處理後的結果進行歸併,得到最終的結果。

BigTable(Bigtable: A Distributed Storage System for Structured Data) :在分布式系統上存儲結構化數據的一個解決方案,解決了巨大的Table的管理、負載均衡的問題.

Google在2003~2006年發表了這三篇論文之後,一時之間引起了轟動,但是Google並沒有將MapReduce開源。在這種情況下Hadoop就出現了,Doug Cutting在Google的3篇論文的理論基礎上開發了Hadoop,此後Hadoop不斷走向成熟,目前Facebook、IBM、ImageShack等知名公司都在使用Hadoop運行他們的程序。

分布式計算的優勢:

可以集成諸多低配的計算機(成千上萬臺)進行高並發的儲存與計算,從而達到與超級計算機媲美的處理能力。

三、用python寫並行程序

在介紹如何使用python寫並行程序之前,我們需要先補充幾個概念,分別是進程、線程與全局解釋器鎖(Global Interpreter Lock, GIL)。

3.1 進程與線程

進程(process):

在面向線程設計的系統(如當代多數作業系統、Linux 2.6及更新的版本)中,進程本身不是基本運行單位,而是線程的容器。

進程擁有自己獨立的內存空間,所屬線程可以訪問進程的空間。

程序本身只是指令、數據及其組織形式的描述,進程才是程序的真正運行實例。例如,Visual Studio開發環境就是利用一個進程編輯源文件,並利用另一個進程完成編譯工作的應用程式。

線程(threading):

進程與線程有兩個主要的不同點,其一是進程包含線程,線程使用進程的內存空間,當然線程也有自己的私有空間,但容量小;其二是進程有各自獨立的內存空間,互不幹擾,而線程是共享內存空間。

圖三展示了進程、線程與CPU之間的關係。在圖三中,進程一與進程二都含有3個線程,CPU會按照線程來分配任務,如圖中4個CPU同時執行前4個線程,後兩個標紅線程處於等待狀態,在CPU運行完當前線程時,等待的線程會被喚醒並進入CPU執行。通常,進程含有的線程數越多,則它佔用CPU的時間會越長。

圖三、進程、線程與CPU關係

3.2 全局解釋器鎖GIL:

GIL是電腦程式設計語言解釋器用於同步線程的一種機制,它使得任何時刻僅有一個線程在執行。即便在多核心處理器上,使用 GIL 的解釋器也只允許同一時間執行一個線程。Python的Cpython解釋器(普遍使用的解釋器)使用GIL,在一個Python解釋器進程內可以執行多線程程序,但每次一個線程執行時就會獲得全局解釋器鎖,使得別的線程只能等待,由於GIL幾乎釋放的同時就會被原線程馬上獲得,那些等待線程可能剛喚醒,所以經常造成線程不平衡享受CPU資源,此時多線程的效率比單線程還要低下。在python的官方文檔裡,它是這樣解釋GIL的:

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

可以說它的初衷是很好的,為了保證線程間的數據安全性;但是隨著時代的發展,GIL卻成為了python並行計算的最大障礙,但這個時候GIL已經遍布CPython的各個角落,修改它的工作量太大,特別是對這種開源性的語音來說。但幸好GIL只鎖了線程,我們可以再新建解釋器進程來實現並行,那這就是multiprocessing的工作了。

3.3 multiprocessing

multiprocessing是python裡的多進程包,通過它,我們可以在python程序裡建立多進程來執行任務,從而進行並行計算。 官方文檔 如下所述:

The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads.

我們接下來介紹下multiprocessing的各個接口:

3.3.1 進程process

multiprocessing.Process(target=None, args=())
target: 可以被run()調用的函數,簡單來說就是進程中運行的函數
args: 是target的參數
process的方法:
start(): 開始啟動進程,在創建process之後執行
join([timeout]):阻塞目前父進程,直到調用join方法的進程執行完或超時(timeout),才繼續執行父進程
terminate():終止進程,不論進程有沒有執行完,儘量少用。

示例1

from multiprocessing import Process
def f(name):
print 'hello', name
if __name__ == '__main__':
p = Process(target=f, args=('bob',)) # p進程執行f函數,參數為'bob',注意後面的「,」
p.start() # 進程開始
p.join() # 阻塞主線程,直至p進程執行結束

3.3.2 進程池Process Pools

class multiprocessing.Pool([processes])
processes是進程池中的進程數,默認是本機的cpu數量
方法:
apply(func[, args[, kwds]])進程池中的進程進行func函數操作,操作時會阻塞進程,直至生成結果。
apply_async(func[, args[, kwds[, callback]]])與apply類似,但是不會阻塞進程
map(func, iterable[, chunksize])進程池中的進程進行映射操作
map_async(func, iterable[, chunksize[, callback]])
imap(func, iterable[, chunksize]):返回有序迭代器
imap_unordered(func, iterable[, chunsize]):返回無序迭代器
close():禁止進程池再接收任務
terminate():強行終止進程池,不論是否有任務在執行
join():在close()或terminate()之後進行,等待進程退出

示例2

from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
p = Pool(5) # 創建有5個進程的進程池
print(p.map(f, [1, 2, 3])) # 將f函數的操作給進程池

3.3.3 Pipes & Queues

multiprocessing.Pipe([duplex])
返回兩個連接對象(conn1, conn2),兩個連接對象分別訪問pipe的頭和尾,進行讀寫操作
Duplex: True(default),創建的pipe是雙向的,也即兩端都可以進行讀寫;若為False,則pipe是單向的,僅可以在一端讀,另一端寫,此時與Queue類似。
multiprocessing.Queue([maxsize])
qsize():返回queue中member數量
empty():如果queue是空的,則返回true
full():如果queue中member數量達到maxsize,則返回true
put(obj):將一個object放入到queue中
get():從隊列中取出一個object並將它從queue中移除,FIFO原則
close():關閉隊列,並將緩存的object寫入pipe

示例

from multiprocessing import Pool
import time
def f(x):
return x*x
if __name__ == '__main__':
pool = Pool(processes=4) # start 4 worker processes
result = pool.apply_async(f, (10,)) # evaluate "f(10)" asynchronously in a single process
print result.get(timeout=1) # prints "100" unless your computer is *very* slow
print pool.map(f, range(10)) # prints "[0, 1, 4,..., 81]"
it = pool.imap(f, range(10))
print it.next() # prints "0"
print it.next() # prints "1"
print it.next(timeout=1) # prints "4" unless your computer is *very* slow
result = pool.apply_async(time.sleep, (10,))
print result.get(timeout=1) # raises multiprocessing.TimeoutError

3.3.4 進程鎖multiprocessing.Lock

當一個進程獲得(acquire)鎖之後,其它進程在想獲得鎖就會被禁止,可以保護數據,進行同步處理。
acquire(block=True, timeout=None):嘗試獲取一個鎖,如果block為true,則會在獲得鎖之後阻止其它進程再獲取鎖。
release():釋放鎖

3.3.5 共享內存——Value, Array

共享內存通常需要配合進程鎖來處理,保證處理的順序相同。

multiprocessing.Value(typecode_or_type, *args[, lock])
返回一個ctype對象,
創建c = Value(『d』, 3.14),調用c.value()
multiprocessing.Array(typecode_or_type, size_or_initializer, *, lock=True)
返回一個ctype數組,只能是一維的
Array(『i』, [1, 2, 3, 4])

3.3.6 其它方法

multiprocessing.active_children():返回當前進程的所有子進程
multiprocessing.cpu_count():返回本計算機的cpu數量
multiprocessing.current_process():返回當前進程

3.3.7 注意事項:

儘量避免共享數據

所有對象都儘量是可以pickle的

避免使用terminate強行終止進程,以造成不可預料的後果

有隊列的進程在終止前隊列中的數據需要清空,join操作應放到queue清空後

明確給子進程傳遞資源、參數

windows平臺另需注意:

四、multiprocessing實戰

process、lock與value嘗試:

import multiprocessing as mp
import time
def job(v, num, l):
l.acquire() # 鎖住
for _ in range(5):
time.sleep(0.1)
v.value += num # 獲取共享內存
print(v.value)
l.release() # 釋放
def multicore():
l = mp.Lock() # 定義一個進程鎖
#l = 1
v = mp.Value('i', 0) # 定義共享內存
p1 = mp.Process(target=job, args=(v,1,l)) # 需要將lock傳入
p2 = mp.Process(target=job, args=(v,3,l))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__=='__main__':
multicore()

上述代碼即對共享內存疊加5次,p1進程每次疊加1,p2進程每次疊加3,為了避免p1與p2在運行時搶奪共享數據v,在進程執行時鎖住了該進程,從而保證了執行的順序。我測試了三個案例:

直接運行上述代碼輸出[1, 2, 3, 4, 5, 8, 11, 14, 17, 20],運行時間為1.037s

在1的基礎上注釋掉鎖(上述注釋了三行),在沒有鎖的情況下,輸出[1, 4, 5, 8, 9, 12, 13, 15, 14, 16],運行時間為0.53s

在2的基礎上將p1.join()調到p2.start()前面,輸出為[1, 2, 3, 4, 5, 8, 11, 14, 17, 20],運行時間為1.042s.

可以發現,沒鎖的情況下調整join可以取得與加鎖類似的結果,這是因為join即是阻塞主進程,直至當前進程結束才回到主進程,若將p1.join()放到p1.start()後面,則會馬上阻塞主進程,使得p2要稍後才開始,這與鎖的效果一樣。

如果如上述代碼所示,p1.join()在p2.start()後面,雖然是p1先join(),但這時只是阻塞了主進程,而p2是兄弟進程,它已經開始了,p1就不能阻止它了,所以這時如果沒鎖的話p1與p2就是並行了,運行時間就是一半,但因為它們爭搶共享變量,所以輸出就變得不確定了。

pool

import multiprocessing as mp
#import pdb
def job(i):
return i*i
def multicore():
pool = mp.Pool()
#pdb.set_trace()
res = pool.map(job, range(10))
print(res)
res = pool.apply_async(job, (2,))
# 用get獲得結果
print(res.get())
# 迭代器,i=0時apply一次,i=1時apply一次等等
multi_res = [pool.apply_async(job, (i,)) for i in range(10)]
# 從迭代器中取出
print([res.get() for res in multi_res])
multicore()

pool其實非常好用,特別是map與apply_async。通過pool這個接口,我們只有指定可以並行的函數與函數參數列表,它就可以自動幫我們創建多進程池進行並行計算,真的不要太方便。pool特別適用於數據並行模型,假如是消息傳遞模型那還是建議自己通過process來創立進程吧。

總結

小子這次主要是按自己的理解把並行計算理了下,對進程、線程、CPU之間的關係做了下闡述,並把python的multiprocessing這個包拎了拎,個人感覺這個裡面還大有學問,上次我一個師兄用python的process來控制單次迭代的運行時間(運行超時就跳過這次迭代,進入下一次迭代)也是讓我漲了見識,後面還要多多學習啊。

*聲明:本文於網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯繫我們刪除或授權事宜。

覺得不錯,點個「在看」然後轉發出去

相關焦點

  • python應用(2):寫個python程序給自己用
    用python寫一個程序,然後在命令行上執行,看不到界面(UI),這種程序很常見了,叫命令行程序。
  • Python快速入門教程,滿滿都是乾貨
    Python易於學習,而且功能強大,功能多樣的腳本語言使其對應用程式開發具有吸引力。Python的語法和動態類型具有其解釋性質,使其成為許多領域的腳本編寫和快速應用程式開發的理想語言。Python支持多種編程模式,包括面向對象編程,命令式和函數式編程或過程式編程。Python幾乎無所不能,一些常用的開發領域,如Web編程。
  • 最全Python快速入門教程,滿滿都是乾貨
    Python易於學習,而且功能強大,功能多樣的腳本語言使其對應用程式開發具有吸引力。Python的語法和動態類型具有其解釋性質,使其成為許多領域的腳本編寫和快速應用程式開發的理想語言。Python支持多種編程模式,包括面向對象編程,命令式和函數式編程或過程式編程。
  • 總結了 90 條寫 Python 程序的建議
    設計模式 建議50:利用模塊實現單例模式建議51:用mixin模式讓程序更加靈活建議52:用發布-訂閱模式實現鬆耦合建議53:用狀態模式美化代碼6.不僅僅講解工具使用,更是培養你的【策略化思維】特訓營全面專業,由淺入深帶領學習,一環扣一環,課程節奏按照學員需求走,老師教的都是機構投資者用的方法和模式。系統化的教學,讓你掌握的是量化投資的整體框架和投資思路,而不是Python簡單的程式語言或者零零散散的知識碎片。
  • 七夕用python給男朋友寫的小程序,感動哭了.
    七夕將至,給男朋友寫了個小程序,把他感動哭了,把我可累慘了。可樂我也不是程序媛專門敲代碼的,雖然也學過,但也僅局限於用pandas處理一下數據的程度,要寫一個界面並且能讓對方直接打開,有點超綱。但是經過5天的不懈努力,終於也算寫出來了,就長下面這個樣子,其實就是Python裡用tkinter模塊做的一個GUI圖形界面。
  • Python 多進程並行編程實踐 - multiprocessing 模塊
    眾所周知,Python中的GIL限制了Python多線程並行對多核CPU的利用,但是我們仍然可以通過各種其他的方式來讓Python真正利用多核資源, 例如通過C/C++擴展來實現多線程/多進程, 以及直接利用Python的多進程模塊multiprocessing來進行多進程編程。
  • 用Python寫一個安卓APP
    第一時間送達http://youerning.blog.51cto.com/10513771/1733534前言用 Python 寫安卓 APP 肯定不是最好的選擇,目前用 Java 和 kotlin 寫的居多,但是肯定也是一個很偷懶的選擇,而且實在不想學習 Java,再者,就編程而言已經會的就 Python與 Golang(註:Python,Golang 水平都一般),那麼久 Google
  • 英雄聯盟,硬核助威,Python分析掌握全局!
    扣丁學堂在線訓練營,特邀AI教研總監大潘老師,為大家分享【英雄聯盟,硬核助威,Python分析掌握全局】滿滿乾貨,敬請期待。▼扣丁學堂AI教研總監 大潘老師千萬級到億萬級PV網站技術架構實現經驗,對java,Hadoop、Scala、Spark、機器學習、神經網絡等大數據技術具有深厚技術功底。
  • 5 分鐘完全掌握 Python 協程
    因為子程序切換不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷,和多線程比,線程數量越多,協程的性能優勢就越明顯第二大優勢就是不需要多線程的鎖機制,因為只有一個線程,也不存在同時寫變量衝突,在協程中控制共享資源不加鎖,只需要判斷狀態就好了,所以執行效率比多線程高很多。
  • 一句查詢讓Python幫忙自己寫程序
    ,學會了Python的語法,但是轉頭就忘了,或者是想實現一個基礎的功能,但是程序不知道怎麼去寫。自己去網上找相應的問題,然後挑選合適的程序進行修改,非常的耗時耗力。今天,小編就帶領大家藉助一個新的Python庫來解決這個問題,讓大家只通過一個問題查詢的語句,便可以自動獲得對應的程序,省略自己編程帶來的煩惱。
  • Python中的並行處理:實例編程指南
    在本教程中,您將了解使用python多進程模塊對任何類型的邏輯過程進行並行處理的流程。內容:1. 簡介2. 最多可以進行多少個並行處理?  3. 什麼是同步和異步執行?4. 問題討論:計算每行中給定數值範圍內的元素個數    不使用並行處理的解答5. 如何進行函數並行化?
  • 第一個Python程序
    說的簡單一些,後綴名就是為了讓我們可以快速打開文件,這點在windows下尤為明顯,linux並不顯著。其實,說白了,python源文件也是文本文件,用.py結尾也是為了讓python解釋器可以直接識別這個文件進而快速調用。換一個後綴名其實同樣可以使用。
  • 用Python寫了自動化交易程序, 2年躺著賺了200萬?!
    1天——下載並安裝好學習環境:到www.python.org網站上下載一個Python3.0以上的版本。(建議初學者,不要下載具有IDE功能的集成開發環境,比如Eclipse插件等。)通過學習語法,掌握Python中的關鍵字語法,函數語法,數學表達式、變量、數據結構、語法等等等。2周——看完基礎後,就是做一些小項目鞏固基礎,Python具備很好的交互學習模式,對於書本上的例子我們可以通過交互平臺進行操練,通過練習加深印象,達到學習掌握的目的。
  • Python | 你用 Python 寫過最牛逼的程序/腳本是什麼?
    編譯:Python開發者 - Jake_on  英文:Quorahttp://python.jobbole.com/85986/有網友在 Quora 上提問,「你用 Python 寫過最牛逼的程序/腳本是什麼?」。本文摘編了 3 個國外程式設計師的多個小項目,含代碼。
  • 用Python寫個在線Python的網站怎麼樣
    前幾天,一個朋友提出了一個建議,如何用python寫出python的解釋器,我感覺這是一個很好的問題,於是就去看看,打算用python寫一個試試
  • 用Python寫一個基於Web的物聯網應用程式
    雖然系統運行正常,但很快就產生了新的需求:當有嘉賓或者學生來參觀智慧農場系統的時候,如何快速展示這一系統的「物聯」功能?畢竟打開SIoT(MQTT伺服器)的Web管理頁面,再進行演示總不夠便捷,也難以體現個性化。這就需要寫一個物聯網應用程式,對接入的各個節點設備進行直觀的管理。當然,我們期望這個物聯網應用程式的開發難度不能太高,最好學生也能夠開發。
  • 乾貨分享:兩周內零基礎搞定第一個Python程序
    當然可以,但好像沒有現成的工具可以用。這當然不能難倒我們CAE工程師了,沒有程序,就自己寫一個吧!任務清單:python編寫一個程序,轉化*.pch文件成Excel文件時間期限:2周編程基礎:Python零基礎以下為完成的程序及操作演示:劃重點!乾貨分享開始。
  • 用Python+小程序實現詩詞大會的飛花令
    當時作為語音行業一員對此十分感興趣,想著能不能用程序實現一個,思考技術方案的時候發現最大難度就是數據,遂求助 碼農交友社區(https://github.com/),發現了開源庫 chinese-poetry(https://github.com/chinese-poetry/chinese-poetry),然後結合免費的百度語音識別,整個項目就成了。
  • python-for-android:將Python程序打包為APK
    是Android上Python應用程式的封裝程序。您可以創建自己的Python程序,包括所需的模塊和依賴項與您自己的代碼捆綁在一起。功能包括:有關文檔和支持,請參閱:在2015年,這個工具被重寫,更新出更容易使用和擴展的界面。新的工具通過內置的pygame引導包含所有與distribute.sh和build.py相同的功能。舊版本地址安裝按照 快速入門說明 安裝並開始創建APK。
  • 當代研究生應當掌握的5種Pytorch並行訓練方法(單機多卡)
    在打開 b 站 「學習」 之前看著那空著一半的顯卡決定寫點什麼餵飽它們~因此,從 V100-PICE/V100/K80 中各拿出 4 張卡,試驗一下哪種分布式學習庫速度最快!這下終於能把剩下的顯存吃完啦,又是老師的勤奮好學生啦(我真是個小機靈鬼)!