R скрипт запускается на внешнем кластере без улучшения производительности - PullRequest
0 голосов
/ 24 июня 2018

Я использую подход к моделированию тем, который хорошо работает на моем компьютере в RStudio, за исключением того, что это занимает много лет.Поэтому я использую кластер Linux.Тем не менее, я также запрашиваю большую емкость, она на самом деле не ускоряется:

Извините, я зеленый рог ... Так что это то, что я использую в оболочке конкурса.:

salloc -N 240 --mem=61440 -t 06:00:00 -p med 
#!/bin/sh

#SBATCH --nodes=200
#SBATCH --time=06:00:00
#SBATCH --partition=med
#SBATCH --mem=102400
#SBATCH --job-name=TestJobUSERNAME
#SBATCH --mail-user=username@ddomain.com
#SBATCH --mail-type=ALL
#SBATCH --cpus-per-task=100

squeue –u username
cd /work/username/data
module load R
export OMP_NUM_THREADS=100
echo "sbatch: START SLURM_JOB_ID $SLURM_JOB_ID (SLURM_TASK_PID $SLURM_TASK_PID) on $SLURMD_NODENAME" 
echo "sbatch: SLURM_JOB_NODELIST $SLURM_JOB_NODELIST" 
echo "sbatch: SLURM_JOB_ACCOUNT $SLURM_JOB_ACCOUNT"

Rscript myscript.R

Я почти уверен, что есть что-то.неправильно с моими данными, потому что:

  • это не очень быстро (но мой R-код, конечно, также может быть медленным - поэтому я пробовал различные R-коды с разными типами вычислений)
  • если я использую 1 или 200 узлов, вычисление одного и того же сценария R занимает почти одинаковое время (хотя должно быть не менее 244 узлов)
  • результаты эха не дают полной информации иЯ не получаю уведомления по электронной почте

, так что это мои типичные результаты:

#just very small request to copy/paste the results, usually I request the one above
[username@gw02 ~]$ salloc -N 2 --mem=512 -t 00:10:00 -p short
salloc: Granted job allocation 1234567
salloc: Waiting for resource configuration
salloc: Nodes cstd01-[218-219] are ready for job
Disk quotas for user username (uid 12345):
                 --    disk space     --
Filesystem       limit  used avail  used
/home/user         32G  432M   32G    2%
/work/user          1T  219M 1024G    0%

[username@gw02 ~]$ squeue -u username 
      JOBID   PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
      1234567     short     bash username  R       2:14      2 cstd01-[218-219]

#(directory, module load, etc.)

#missing outcomes for SLURM_TAST_PID and SLUMD_NODENAME: 
[username@gw02 data]$ echo "sbatch: START SLURM_JOB_ID $SLURM_JOB_ID (SLURM_TASK_PID $SLURM_TASK_PID) on $SLURMD_NODENAME"
sbatch: START SLURM_JOB_ID 1314914 (SLURM_TASK_PID ) on

Кто-нибудь может помочь?Спасибо вам большое!

РЕДАКТИРОВАТЬ: Как отмечает Ральф Стубнер в своем комментарии, я не делаю распараллеливание в R-коде.Я понятия не имею, как это сделать.Вот пример расчета:

# Create the data frame
col1 <- runif (12^5, 0, 2)
col2 <- rnorm (12^5, 0, 2)
col3 <- rpois (12^5, 3)
col4 <- rchisq (12^5, 2)
df <- data.frame (col1, col2, col3, col4)
# Original R code: Before vectorization and pre-allocation
system.time({
  for (i in 1:nrow(df)) { # for every row
    if ((df[i, "col1"] + df[i, "col2"] + df[i, "col3"] + df[i, "col4"]) > 4) { # check if > 4
      df[i, 5] <- "greater_than_4" # assign 5th column
    } else {
      df[i, 5] <- "lesser_than_4" # assign 5th column
    }
  }
})

... и сокращенный «реальный код»:

library(NLP)
library(tm)
library(SnowballC)
library(topicmodels)
library(lda)
library(textclean)

# load data and create corups
filenames <- list.files(getwd(),pattern='*.txt')
files <- lapply(filenames,readLines)
docs <- Corpus(VectorSource(files))

# clean data (shortened, just two examples) 
docs.adj <- tm_map(docs.adj, removeWords, stopwords('english'))
docs.adj <-tm_map(docs.adj,content_transformer(tolower))

# create document-term matrix
dtm <- DocumentTermMatrix(docs.adj)
dtm_stripped <- removeSparseTerms(dtm, 0.8)
rownames(dtm_stripped) <- filenames
freq <- colSums(as.matrix(dtm_stripped))
ord <- order(freq,decreasing=TRUE)

### find optimal number of k 
burnin <- 10000
iter <- 250
thin <- 50
seed <-list(3)
nstart <- 1
best <- TRUE
seq_start <- 2
seq_end <- length(files)
iteration <- floor(length(files)/5)

best.model <- lapply(seq(seq_start,seq_end, by=iteration), function(k){LDA(dtm_stripped, k, method = 'Gibbs',control=list(nstart=nstart, seed = seed, best=best, burnin = burnin, iter = iter, thin=thin))})
best.model.logLik <- as.data.frame(as.matrix(lapply(best.model, logLik)))
best.model.logLik.df <- data.frame(topics=c(seq(seq_start,seq_end, by=iteration)), LL=as.numeric(as.matrix(best.model.logLik)))
optimal_k <- best.model.logLik.df[which.max(best.model.logLik.df$LL),]
print(optimal_k)

### do topic modeling with more iterations on optimal_k
burnin <- 4000
iter <- 1000
thin <- 100
seed <-list(2003,5,63)
nstart <- 3
best <- TRUE
ldaOut <-LDA(dtm_stripped,optimal_k, method='Gibbs', control=list(nstart=nstart, seed = seed, best=best, burnin = burnin, iter = iter, thin=thin))

1 Ответ

0 голосов
/ 24 июня 2018

Беглый взгляд на ваш R-скрипт выглядит так:

best.model <- lapply(seq(seq_start,seq_end, by=iteration), function(k){
  LDA(dtm_stripped, k, method = 'Gibbs', control=list(nstart=nstart, seed = seed, best=best, burnin = burnin, iter = iter, thin=thin))
})

, где происходит большая часть времени обработки.Здесь вы можете попытаться распараллелить код, используя future_lapply() вместо lapply(), то есть

best.model <- future_lapply(seq(seq_start,seq_end, by=iteration), function(k){
  LDA(dtm_stripped, k, method = 'Gibbs', control=list(nstart=nstart, seed = seed, best=best, burnin = burnin, iter = iter, thin=thin))
}, future.seed = TRUE)

Я также добавил future.seed = TRUE, чтобы убедиться, что генерация случайных чисел статистически достоверна при параллельной работе,Функция future_lapply() находится в пакете future.apply (*), поэтому вам нужно выполнить:

library(future.apply)

вверху вашего скрипта.Теперь есть еще одна последняя вещь, которую вам нужно сделать - вы должны указать, чтобы она работала параллельно (по умолчанию - последовательная), добавив:

plan(multiprocess)

также вверху (после присоединения future.apply).По умолчанию используется то, какие ядра «доступны», где «доступно» означает, что оно также гибко по отношению к числу ядер, которые планировщик HPC (например, Slurm) выделяет для вашей работы.Если вы попробуете описанное выше на своей локальной машине, по умолчанию будет использовано количество ядер, которое у него есть.То есть вы можете проверить свой код также на своем локальном компьютере, и вы должны увидеть некоторое ускорение.Когда вы знаете, что это работает, вы можете повторно запустить его на кластере через выделение Slurm, и оно должно работать там из коробки - но работать с более параллельными процессами.

Вы можете найти мой пост в блоге.на future.apply с 2018-06-23 полезно - в конце есть несколько часто задаваемых вопросов.

(*) Отказ от ответственности: я являюсь автором future.apply.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...