隨著單細(xì)胞技術(shù)的成熟,單細(xì)胞數(shù)據(jù)分析往往不再是單個組織樣本长酗,這有時候在計算(資源與時間)上是一個挑戰(zhàn)纽谒。為此蜘拉,Seurat也提供了可以探索的并行策略萨西。鑒于入門單細(xì)胞數(shù)據(jù)分析的同事大多不是計算機(jī)出身,我們借助知乎的回答來解釋一下什么是并行:
你吃飯吃到一半旭旭,電話來了谎脯,你一直到吃完了以后才去接,這就說明你不支持并發(fā)也不支持并行您机。
你吃飯吃到一半穿肄,電話來了繁成,你停了下來接了電話颠锉,接完后繼續(xù)吃飯生均,這說明你支持并發(fā)。
你吃飯吃到一半仲闽,電話來了,你一邊打電話一邊吃飯僵朗,這說明你支持并行赖欣。
并發(fā)的關(guān)鍵是你有處理多個任務(wù)的能力,不一定要同時验庙。
并行的關(guān)鍵是你有同時處理多個任務(wù)的能力顶吮。
所以我認(rèn)為它們最關(guān)鍵的點就是:是否是『同時』。
作者:知乎用戶
鏈接:https://www.zhihu.com/question/33515481/answer/58849148
來源:知乎
著作權(quán)歸作者所有粪薛。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)悴了,非商業(yè)轉(zhuǎn)載請注明出處。
在數(shù)據(jù)分析過程中违寿,比如我們計算差異基因湃交,其實是單個基因的計算,一般是算完一個再算下一個藤巢,并行的意思就是同時計算搞莺,以節(jié)約時間。
在Seurat中掂咒,我們選擇使用future
的并行化框架才沧。在本文中,我們將演示如何從用戶的角度利用某些Seurat函數(shù)的future
實現(xiàn)绍刮。如果您有興趣了解更多關(guān)于future
框架的內(nèi)容温圆,請參閱這個R包文檔以獲得全面和詳細(xì)的描述。
如何使用呢录淡?
要訪問Seurat中的函數(shù)的并行版本捌木,需要加載future
的包并設(shè)置plan
。該plan
將指定如何執(zhí)行該函數(shù)嫉戚。默認(rèn)行為是以非并行的方式(順序地)計算的刨裆。為了實現(xiàn)并行(異步)行為澈圈,我們通常推薦“多進(jìn)程”策略。默認(rèn)情況下帆啃,這將使用所有可用的內(nèi)核瞬女,但是您可以設(shè)置workers參數(shù)來限制并發(fā)的數(shù)量。
首先應(yīng)該檢查你的計算機(jī)系統(tǒng)是否支持R的并行努潘。
library(future)
# check the current active plan
plan()
sequential:
- args: function (expr, envir = parent.frame(), substitute = TRUE, lazy = FALSE, seed = NULL, globals = TRUE, local = TRUE, earlySignal = FALSE, label = NULL, ...)
- tweaked: FALSE
- call: NULL
# change the current plan to access parallelization
plan("multiprocess", workers = 4)
plan()
## multiprocess:
## - args: function (expr, envir = parent.frame(), substitute = TRUE, lazy = FALSE, seed = NULL, globals = TRUE, workers = 4, gc = FALSE, earlySignal = FALSE, label = NULL, ...)
## - tweaked: TRUE
## - call: plan("multiprocess", workers = 4)
‘Futurized’ functions in Seurat
再看看Seurat哪些函數(shù)可以使用并行诽偷。
編寫以下函數(shù)是為了利用future
的框架,如果當(dāng)前plan
設(shè)置正確疯坤,這些函數(shù)將被并行化报慕。重要的是,調(diào)用函數(shù)的方式不變压怠。
NormalizeData
ScaleData
JackStraw
FindMarkers
FindIntegrationAnchors
FindClusters - if clustering over multiple resolutions
例如眠冈,要運行findmarker的并行版本,只需設(shè)置計劃并像往常一樣調(diào)用該函數(shù)菌瘫。
library(Seurat)
pbmc <- readRDS("../data/pbmc3k_final.rds")
# Enable parallelization
plan("multiprocess", workers = 4)
markers <- FindMarkers(pbmc, ident.1 = "NK", verbose = FALSE)
并行的比較
在這里蜗顽,我們將對具有并行化和不具有并行化的相同函數(shù)調(diào)用的運行時進(jìn)行一個簡短的比較。請注意雨让,雖然我們預(yù)期使用并行化策略將減少上面列出的函數(shù)的運行時雇盖,但是這種減少的幅度將取決于許多因素(例如數(shù)據(jù)集的大小、工作人員的數(shù)量栖忠、系統(tǒng)的規(guī)格崔挖、未來的策略等)。下面的基準(zhǔn)測試是在運行Ubuntu 16.04.5 LTS和Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz和96 GB RAM的桌面計算機(jī)上進(jìn)行的娃闲。
timing.comparisons <- data.frame(fxn = character(), time = numeric(), strategy = character())
plan("sequential")
start <- Sys.time()
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt", verbose = FALSE)
end <- Sys.time()
timing.comparisons <- rbind(timing.comparisons, data.frame(fxn = "ScaleData", time = as.numeric(end -
start, units = "secs"), strategy = "sequential"))
start <- Sys.time()
markers <- FindMarkers(pbmc, ident.1 = "NK", verbose = FALSE)
end <- Sys.time()
timing.comparisons <- rbind(timing.comparisons, data.frame(fxn = "FindMarkers", time = as.numeric(end -
start, units = "secs"), strategy = "sequential"))
plan("multiprocess", workers = 4)
start <- Sys.time()
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt", verbose = FALSE)
end <- Sys.time()
timing.comparisons <- rbind(timing.comparisons, data.frame(fxn = "ScaleData", time = as.numeric(end -
start, units = "secs"), strategy = "multiprocess"))
start <- Sys.time()
markers <- FindMarkers(pbmc, ident.1 = "NK", verbose = FALSE)
end <- Sys.time()
timing.comparisons <- rbind(timing.comparisons, data.frame(fxn = "FindMarkers", time = as.numeric(end -
start, units = "secs"), strategy = "multiprocess"))
來看看效果
library(ggplot2)
library(cowplot)
ggplot(timing.comparisons, aes(fxn, time)) + geom_bar(aes(fill = strategy), stat = "identity", position = "dodge") +
ylab("Time(s)") + xlab("Function") + theme_cowplot()
FAQ
我的進(jìn)度條去哪了?
不幸的是虚汛,當(dāng)以任何并行計劃模式運行這些函數(shù)時,您將丟失進(jìn)度條皇帮。這是由于一些技術(shù)限制在未來的框架和R一般卷哩。如果您想監(jiān)視函數(shù)的進(jìn)度,就需要放棄并行化属拾,而使用plan(“sequential”)将谊。如果我一直看到以下錯誤,我應(yīng)該怎么做?
Error in getGlobalsAndPackages(expr, envir = envir, globals = TRUE) :
The total size of the X globals that need to be exported for the future expression ('FUN()') is X GiB. This exceeds the maximum allowed size of 500.00 MiB (option 'future.globals.maxSize'). The X largest globals are ...
或者某些函數(shù)渐白,每個worker需要訪問某些全局變量尊浓。如果這些值大于默認(rèn)限制,您將看到此錯誤纯衍。要解決這個問題栋齿,可以設(shè)置選項(future.globals。maxSize = X),其中X是允許的最大大小(以字節(jié)為單位)瓦堵。因此基协,要將其設(shè)置為1GB,需要運行options(future.globals菇用。maxSize = 1000 * 1024^2)澜驮。請注意,這將增加您的RAM使用量惋鸥,因此請謹(jǐn)慎地設(shè)置這個數(shù)字杂穷。
說到底Seurat不過是個R包,想要并行計算是要懂一些R里面并行原理的:由內(nèi)而外釋放R的力量||摘自《R大數(shù)據(jù)分析實用指南》卦绣。特別地耐量,當(dāng)我們在R中計算的中途突然發(fā)現(xiàn)某個任務(wù)報錯說超出內(nèi)存了,怎么辦呢迎卤?
使用更少的線程進(jìn)行并行拴鸵;
如果你的電腦內(nèi)存非常小,有一個簡單的方法確定你的最大使用線程:max cores = memory.limit() / memory.size()蜗搔;
將大量的并行分小部分進(jìn)行;
在代碼中多使用rm()刪除沒用的變量八堡,使用gc()回收內(nèi)存空間樟凄;