HPC集群使用(SLURM/PBS)¶
一句话说明: HPC集群就是一台大家排队共用的超级计算机——你写好任务脚本提交排队,系统自动分配资源帮你跑,本篇教你SLURM/PBS的核心用法和生信场景实操。
目录¶
- 什么是HPC集群
- SLURM核心概念
- 编写sbatch脚本
- 资源申请策略
- 常见SLURM脚本模板
- PBS对比
- 模块管理(module)
- 集群上的conda环境管理
- 生信pipeline在集群上运行
- 面试怎么答
- 速查表
- 延伸资源
1. 什么是HPC集群¶
1.1 白话解释¶
HPC(High Performance Computing,高性能计算)集群,可以理解为:
- 一堆电脑(节点)连在一起,共享一个文件系统
- 有个"调度员"(作业调度器)负责排队、分配资源
- 你不能直接霸占一台机器,而是提交一个任务申请,写清楚需要多少CPU、多少内存、跑多久,调度员给你安排
1.2 集群的基本结构¶
┌──────────────────────────────────────────┐
│ 登录节点 (Login Node) │ ← 你SSH登录到这里
│ ⚠️ 不要在这里跑大任务! │
└──────────┬───────────────────────────────┘
│ 提交任务 (sbatch/qsub)
▼
┌──────────────────────────────────────────┐
│ 调度器 (SLURM / PBS) │ ← 排队分配资源
└──────────┬───────────────────────────────┘
│ 分配到具体节点
▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 计算节点1│ │ 计算节点2│ │ 计算节点3│ ← 实际跑任务的地方
│ 64核/256G│ │ 64核/256G│ │ 8xGPU │
└─────────┘ └─────────┘ └─────────┘
│
▼
┌──────────────────────────────────────────┐
│ 共享存储 (/home, /data) │ ← 所有节点都能访问
└──────────────────────────────────────────┘
1.3 为什么生信需要HPC¶
| 生信任务 | 典型资源需求 | 为什么需要集群 |
|---|---|---|
| 宏基因组组装(MEGAHIT) | 50-200GB内存 | 普通电脑内存不够 |
| 序列比对(Bowtie2/BWA) | 多核并行加速 | 一个样本跑1小时,100个样本需要并行 |
| Kraken2物种注释 | 70GB+内存(标准库) | 需要大内存节点 |
| 深度学习模型训练 | GPU | 需要GPU节点 |
| 批量质控(fastp × 100) | 数组任务 | 100个样本并行跑 |
2. SLURM核心概念¶
SLURM(Simple Linux Utility for Resource Management)是目前最主流的集群调度系统(版本已到25.11)。
2.1 关键术语¶
| 术语 | 英文 | 白话解释 | 类比 |
|---|---|---|---|
| Partition | 分区 | 一组计算节点的集合,类似"不同窗口" | 银行的普通窗口vs VIP窗口 |
| Node | 节点 | 集群中的一台服务器 | 银行的一个柜员 |
| Job | 作业 | 你提交的一个计算任务 | 你的一个业务办理请求 |
| CPU/Core | 核心 | 一个节点上的处理器核心数 | 柜员有几只手能同时干活 |
| QOS | 服务质量 | 优先级和资源限制策略 | VIP客户优先办理 |
2.2 核心命令¶
# ===== 提交任务 =====
sbatch my_job.sh # 提交批处理脚本(最常用!)
# 白话:把你的任务扔到排队队列里
srun hostname # 直接在分配的节点上运行一个命令(交互式)
# 白话:当场申请资源跑一个命令
salloc -n 4 -t 2:00:00 # 申请资源但不立即运行任务(交互式会话)
# 白话:先占个座位,等会儿再点菜
# ===== 查看任务 =====
squeue # 查看所有排队/运行中的任务
# 白话:看看队排到哪了
squeue -u $USER # 只看自己的任务
# 白话:看看我自己的号排到哪了
squeue -j 12345 # 查看指定任务的状态
# 白话:查一下这个号的状态
# ===== 取消任务 =====
scancel 12345 # 取消指定任务
# 白话:不排了,取消这个号
scancel -u $USER # 取消自己所有任务
# 白话:我所有的号都不要了
# ===== 查看集群信息 =====
sinfo # 查看集群分区和节点状态
# 白话:看看哪些窗口开着、哪些窗口忙
scontrol show job 12345 # 查看任务详细信息
# 白话:看这个任务的详细收据
sacct -j 12345 # 查看已完成任务的资源使用情况
# 白话:回顾这个任务实际用了多少资源(事后分析)
3. 编写sbatch脚本¶
3.1 完整模板(生信任务示例:fastp质控)¶
#!/bin/bash
#============================================================
# SLURM 作业脚本模板 - fastp质控
# 作者:[用户]
# 日期:2026-05-03
#============================================================
#---------- SLURM 参数设置(每行一个#SBATCH) ----------
#SBATCH --job-name=fastp_qc # 任务名称(方便在squeue中识别)
#SBATCH --output=logs/%x_%j.out # 标准输出文件(%x=任务名, %j=任务ID)
#SBATCH --error=logs/%x_%j.err # 错误输出文件
#SBATCH --partition=normal # 提交到哪个分区(问管理员有哪些分区)
#SBATCH --nodes=1 # 申请1个节点(大多数生信任务只需要1个)
#SBATCH --ntasks=1 # 1个任务(不是MPI并行时设为1)
#SBATCH --cpus-per-task=8 # 每个任务用8个CPU核心
#SBATCH --mem=16G # 申请16GB内存
#SBATCH --time=04:00:00 # 最长运行时间4小时(超时会被杀掉!)
#SBATCH --mail-type=END,FAIL # 任务结束或失败时发邮件通知
#SBATCH --mail-user=your@email.com # 接收通知的邮箱
#---------- 环境设置 ----------
# 打印任务开始信息(方便调试)
echo "任务开始时间: $(date)" # 记录开始时间
echo "运行节点: $(hostname)" # 记录在哪个节点上跑
echo "工作目录: $(pwd)" # 记录当前目录
# 加载需要的软件模块
module purge # 先清除所有已加载模块(避免冲突)
module load fastp/1.3.3 # 加载fastp模块
# 或者激活conda环境(二选一)
# source activate qc_env
#---------- 定义变量 ----------
INPUT_DIR="/data/raw_reads" # 原始数据目录
OUTPUT_DIR="/data/clean_reads" # 输出目录
SAMPLE="sample_001" # 样本名称
THREADS=8 # 线程数(和--cpus-per-task一致!)
# 确保输出目录存在
mkdir -p ${OUTPUT_DIR} # -p:如果目录已存在不报错
mkdir -p logs # 创建日志目录
#---------- 主要分析步骤 ----------
echo "开始处理样本: ${SAMPLE}"
fastp \
--in1 ${INPUT_DIR}/${SAMPLE}_R1.fastq.gz \ # 输入:正向reads
--in2 ${INPUT_DIR}/${SAMPLE}_R2.fastq.gz \ # 输入:反向reads
--out1 ${OUTPUT_DIR}/${SAMPLE}_clean_R1.fastq.gz \ # 输出:质控后正向
--out2 ${OUTPUT_DIR}/${SAMPLE}_clean_R2.fastq.gz \ # 输出:质控后反向
--html ${OUTPUT_DIR}/${SAMPLE}_fastp.html \ # 质控报告(HTML格式)
--json ${OUTPUT_DIR}/${SAMPLE}_fastp.json \ # 质控报告(JSON格式)
--thread ${THREADS} \ # 使用的线程数
--qualified_quality_phred 20 \ # 质量值≥20的碱基才保留
--length_required 50 # 过短的reads(<50bp)丢弃
#---------- 结束信息 ----------
echo "任务结束时间: $(date)"
echo "退出状态码: $?" # 0表示成功,非0表示出错
3.2 提交和监控¶
# 提交任务
sbatch fastp_qc.sh
# 输出:Submitted batch job 12345
# 查看任务状态
squeue -u $USER
# JOBID PARTITION NAME USER ST TIME NODES NODELIST
# 12345 normal fastp_qc user R 0:05 1 node01
# ST列:PD=排队中, R=运行中, CG=正在完成
# 查看任务输出(实时跟踪)
tail -f logs/fastp_qc_12345.out
# 任务完成后查看资源使用
sacct -j 12345 --format=JobID,JobName,MaxRSS,Elapsed,State
# MaxRSS:实际使用的最大内存
# Elapsed:实际运行时间
4. 资源申请策略¶
4.1 估算指南¶
| 资源 | 估算方法 | 生信参考值 |
|---|---|---|
| CPU | 看软件文档的-t/--threads参数 | 质控4-8核,比对8-16核,组装16-32核 |
| 内存 | 先小量测试,用sacct看实际使用 | fastp: 4-8G, Kraken2: 8-70G, MEGAHIT: 50-200G |
| 时间 | 先设长一点,后续根据经验缩短 | 质控: 1-2h/样本, 比对: 2-4h/样本, 组装: 6-24h |
| GPU | 只有深度学习任务才需要 | AlphaFold: 1-2 GPU, 模型训练: 1-4 GPU |
4.2 实用技巧¶
# 技巧1:先跑一个小测试,看实际资源使用
sbatch --wrap="fastp -i test_R1.fq.gz -o /dev/null" --mem=4G -t 00:30:00
# 技巧2:查看已完成任务的实际资源使用
sacct -j 12345 --format=JobID,MaxRSS,MaxVMSize,Elapsed
# 根据实际使用量,下次申请时加20-50%余量
# 技巧3:查看分区的空闲资源
sinfo -p normal -o "%N %C %m %G"
# 输出节点名、CPU使用情况、内存、GPU信息
4.3 常见错误¶
| 错误 | 原因 | 解决方法 |
|---|---|---|
slurmstepd: error: Exceeded memory limit | 申请的内存不够 | 增加 --mem |
TIMEOUT | 运行时间超过 --time | 增加时间限制 |
(QOSMaxJobsPerUserLimit) | 超过每人最大任务数 | 等现有任务完成 |
| 任务一直PD | 申请资源太多,排不上 | 减少资源申请或换分区 |
5. 常见SLURM脚本模板¶
5.1 数组任务(Array Job)—— 批量处理100个样本¶
#!/bin/bash
#SBATCH --job-name=fastp_array # 任务名
#SBATCH --array=1-100 # 数组任务:索引从1到100
#SBATCH --cpus-per-task=4 # 每个子任务4核
#SBATCH --mem=8G # 每个子任务8G内存
#SBATCH --time=02:00:00 # 每个子任务最多2小时
#SBATCH --output=logs/fastp_%A_%a.out # %A=主任务ID, %a=数组索引
# 从样本列表文件中读取当前索引对应的样本名
# sample_list.txt 每行一个样本名
SAMPLE=$(sed -n "${SLURM_ARRAY_TASK_ID}p" sample_list.txt)
echo "处理样本 #${SLURM_ARRAY_TASK_ID}: ${SAMPLE}"
module load fastp/1.3.3
fastp \
--in1 raw/${SAMPLE}_R1.fastq.gz \
--in2 raw/${SAMPLE}_R2.fastq.gz \
--out1 clean/${SAMPLE}_R1.fastq.gz \
--out2 clean/${SAMPLE}_R2.fastq.gz \
--thread 4
echo "样本 ${SAMPLE} 处理完成"
5.2 多节点并行(MPI任务)¶
#!/bin/bash
#SBATCH --job-name=mpi_task
#SBATCH --nodes=4 # 使用4个节点
#SBATCH --ntasks-per-node=16 # 每个节点16个进程
#SBATCH --mem-per-cpu=4G # 每个CPU核心4G内存
#SBATCH --time=12:00:00
module load openmpi/4.1.5
# 使用srun启动MPI程序(自动分配到所有节点)
srun my_mpi_program --input data.bin --output result.bin
5.3 GPU任务¶
#!/bin/bash
#SBATCH --job-name=alphafold
#SBATCH --partition=gpu # GPU分区(名称问管理员)
#SBATCH --gres=gpu:1 # 申请1块GPU
#SBATCH --cpus-per-task=8 # 8核CPU(GPU任务也需要CPU配合)
#SBATCH --mem=32G
#SBATCH --time=24:00:00
module load cuda/12.0
module load alphafold/2.3
# 检查GPU是否可用
nvidia-smi
# 运行AlphaFold
alphafold --input=query.fasta --output=results/
6. PBS对比¶
PBS(Portable Batch System)是另一种常见的调度系统(变种有PBS Pro和Torque)。
6.1 PBS核心命令¶
# ===== 提交任务 =====
qsub my_job.pbs # 提交PBS脚本(对应SLURM的sbatch)
# ===== 查看任务 =====
qstat # 查看任务状态(对应squeue)
qstat -f 12345 # 查看任务详情(对应scontrol show job)
qstat -u $USER # 只看自己的任务
# ===== 取消任务 =====
qdel 12345 # 取消任务(对应scancel)
# ===== 查看节点 =====
pbsnodes -a # 查看节点信息(对应sinfo)
6.2 PBS脚本示例¶
#!/bin/bash
#PBS -N fastp_qc # 任务名(对应 --job-name)
#PBS -o logs/fastp.out # 标准输出(对应 --output)
#PBS -e logs/fastp.err # 错误输出(对应 --error)
#PBS -q normal # 队列名(对应 --partition)
#PBS -l nodes=1:ppn=8 # 1节点8核(对应 --nodes + --cpus-per-task)
#PBS -l mem=16gb # 内存(对应 --mem)
#PBS -l walltime=04:00:00 # 运行时间(对应 --time)
#PBS -m ae # 结束/出错时发邮件(对应 --mail-type)
#PBS -M your@email.com # 邮箱(对应 --mail-user)
# PBS要手动进入工作目录(SLURM默认就在提交目录)
cd $PBS_O_WORKDIR
module load fastp/1.3.3
fastp --in1 input_R1.fq.gz --in2 input_R2.fq.gz \
--out1 clean_R1.fq.gz --out2 clean_R2.fq.gz \
--thread 8
7. 模块管理(module)¶
集群上的软件通常用 Environment Modules 管理,而不是每个人自己装。
# 查看所有可用模块
module avail # 列出集群上装了哪些软件
# 白话:看看货架上有什么
# 搜索特定软件
module avail kraken # 搜索包含"kraken"的模块
# 加载模块
module load kraken2/2.1.3 # 加载Kraken2(指定版本)
module load samtools # 加载samtools(默认版本)
# 白话:把软件从货架上拿下来用
# 查看已加载的模块
module list # 显示当前环境中加载了哪些模块
# 卸载模块
module unload kraken2 # 卸载Kraken2
module purge # 卸载所有模块(推荐在脚本开头用)
# 白话:把所有东西放回货架,从干净状态开始
# 查看模块信息
module show kraken2/2.1.3 # 显示这个模块设置了哪些环境变量
8. 集群上的conda环境管理¶
8.1 常见问题¶
集群上用conda的注意事项:
# 问题1:conda装在哪?
# 答:通常装在该home目录下,但home目录空间有限(通常10-50GB)
# 解决:把conda安装到/data或/scratch等大容量目录
conda config --prepend pkgs_dirs /data/$USER/conda/pkgs
conda config --prepend envs_dirs /data/$USER/conda/envs
# 问题2:在sbatch脚本中激活conda环境
# 错误写法:
conda activate bioinfo # ← 在非交互式shell中可能失败
# 正确写法:
source activate bioinfo
# 或者:
eval "$(conda shell.bash hook)" # 先初始化conda
conda activate bioinfo # 再激活环境
# 问题3:conda初始化写在.bashrc中,导致登录很慢
# 解决:把conda初始化放在脚本中按需执行,不要放在.bashrc
8.2 推荐做法¶
#!/bin/bash
#SBATCH --job-name=bio_analysis
# 在脚本中初始化和激活conda
eval "$(conda shell.bash hook)" # 初始化conda(必须)
conda activate bioinfo # 激活环境
# 验证环境
which python # 应该指向conda环境中的python
python --version # 确认版本正确
# ... 运行你的分析 ...
conda deactivate # 任务结束后退出环境(可选)
9. 生信pipeline在集群上运行¶
9.1 Snakemake + SLURM¶
# 方式1:使用 --cluster 参数(传统方式)
snakemake --cluster "sbatch -p normal -c {threads} --mem={resources.mem_mb}M -t {resources.time}" \
--jobs 50 \ # 最多同时提交50个任务
--latency-wait 60 # 等待60秒让文件系统同步
# 方式2:使用 SLURM executor plugin(Snakemake 8.x+ 推荐方式)
# 先安装插件
pip install snakemake-executor-plugin-slurm
# 运行时指定executor
snakemake --executor slurm \
--default-resources slurm_partition=normal mem_mb=8000 runtime=240 \
--jobs 50
在Snakefile中指定资源:
rule fastp:
input:
r1 = "raw/{sample}_R1.fastq.gz",
r2 = "raw/{sample}_R2.fastq.gz"
output:
r1 = "clean/{sample}_R1.fastq.gz",
r2 = "clean/{sample}_R2.fastq.gz"
threads: 8 # CPU核心数
resources:
mem_mb = 16000, # 内存(MB)
runtime = 120 # 时间(分钟)
shell:
"fastp --in1 {input.r1} --in2 {input.r2} "
"--out1 {output.r1} --out2 {output.r2} "
"--thread {threads}"
9.2 Nextflow + SLURM¶
// nextflow.config 中配置SLURM
profiles {
slurm {
process.executor = 'slurm' // 使用SLURM调度器
process.queue = 'normal' // 默认分区
process.cpus = 4 // 默认CPU数
process.memory = '8 GB' // 默认内存
process.time = '4h' // 默认时间
}
}
10. 面试怎么答¶
Q1:你用过HPC集群吗?用的什么调度系统?¶
参考回答: 用过SLURM调度系统。该宏基因组分析流程需要较大的计算资源,比如Kraken2注释需要大内存,MEGAHIT组装需要多核并行,这些都是在集群上通过sbatch提交批处理任务完成的。我会根据不同步骤的需求合理申请资源,比如质控步骤申请8核16G,物种注释申请大内存节点。
Q2:sbatch脚本怎么写?¶
参考回答: 一个标准的sbatch脚本包括两部分:顶部的
#SBATCH指令用于指定资源需求(分区、CPU、内存、时间、输出文件),下面是实际的分析命令。关键是要指定合理的资源量——太少会OOM被杀,太多会排队时间很长。我通常先跑一个小测试,用sacct查看实际资源使用,再调整正式任务的参数。
Q3:怎么批量处理100个样本?¶
参考回答: 使用SLURM的数组任务(Array Job)。设置
#SBATCH --array=1-100,每个子任务通过$SLURM_ARRAY_TASK_ID获取自己的索引,再从样本列表中读取对应的样本名。可以用--array=1-100%10限制同时运行的任务数,避免占用太多资源。
Q4:任务被杀了怎么排查?¶
参考回答: 分几步排查:首先用
sacct -j <jobid> --format=State,ExitCode,MaxRSS查看任务状态和退出码。如果State是OUT_OF_MEMORY,说明内存不够,需要增加--mem。如果是TIMEOUT,说明时间不够。如果是其他错误,查看.err文件中的具体报错信息。
Q5:SLURM和PBS有什么区别?¶
参考回答: 主要是命令名不同:sbatch对应qsub,squeue对应qstat,scancel对应qdel。脚本指令也不同,SLURM用
#SBATCH,PBS用#PBS。功能上差异不大,目前SLURM更主流,大部分新建集群都选SLURM。实际工作中掌握一种,另一种看一下对照表就能快速上手。
11. 速查表¶
11.1 SLURM命令速查¶
| 功能 | 命令 | 说明 |
|---|---|---|
| 提交任务 | sbatch job.sh | 提交批处理脚本 |
| 交互式运行 | srun --pty bash | 申请资源并打开交互式shell |
| 申请资源 | salloc -n4 -t2:00:00 | 分配资源(不运行命令) |
| 查看队列 | squeue -u $USER | 查看自己的任务 |
| 取消任务 | scancel <jobid> | 取消指定任务 |
| 取消全部 | scancel -u $USER | 取消自己所有任务 |
| 集群状态 | sinfo | 查看分区和节点状态 |
| 任务详情 | scontrol show job <id> | 查看运行中任务的详细信息 |
| 历史记录 | sacct -j <id> | 查看已完成任务的资源使用 |
| 节点详情 | scontrol show node <name> | 查看节点配置 |
11.2 常用sbatch参数¶
| 参数 | 示例 | 说明 |
|---|---|---|
--job-name | --job-name=fastp | 任务名 |
--partition | --partition=normal | 分区 |
--nodes | --nodes=1 | 节点数 |
--ntasks | --ntasks=1 | 任务数 |
--cpus-per-task | --cpus-per-task=8 | 每任务CPU核心数 |
--mem | --mem=16G | 总内存 |
--mem-per-cpu | --mem-per-cpu=4G | 每核心内存 |
--time | --time=04:00:00 | 最大运行时间 |
--output | --output=logs/%j.out | 输出文件 |
--error | --error=logs/%j.err | 错误文件 |
--array | --array=1-100%10 | 数组任务 |
--gres | --gres=gpu:2 | GPU申请 |
--mail-type | --mail-type=END,FAIL | 邮件通知类型 |
11.3 SLURM vs PBS 对照表¶
| 功能 | SLURM | PBS/Torque |
|---|---|---|
| 提交任务 | sbatch | qsub |
| 查看任务 | squeue | qstat |
| 取消任务 | scancel | qdel |
| 查看节点 | sinfo | pbsnodes -a |
| 任务详情 | scontrol show job | qstat -f |
| 脚本指令前缀 | #SBATCH | #PBS |
| CPU指定 | --cpus-per-task=8 | -l nodes=1:ppn=8 |
| 内存指定 | --mem=16G | -l mem=16gb |
| 时间指定 | --time=04:00:00 | -l walltime=04:00:00 |
| 数组任务 | --array=1-100 | -t 1-100 |
| 工作目录 | 默认在提交目录 | 需手动 cd $PBS_O_WORKDIR |
| 环境变量-任务ID | $SLURM_JOB_ID | $PBS_JOBID |
| 环境变量-数组索引 | $SLURM_ARRAY_TASK_ID | $PBS_ARRAYID |
12. 延伸资源¶
| 资源 | 说明 |
|---|---|
| SLURM官方文档 | 最权威的参考,V25.11 |
| SLURM Quick Start | 官方入门指南 |
| Snakemake SLURM Plugin | Snakemake 8.x SLURM执行器文档 |
| Nextflow Executors | Nextflow支持的调度器列表 |
| 你所在集群的Wiki/文档 | 每个集群的分区名、资源限制不同,一定要看本地文档 |
记住: HPC集群的核心思想就三步——写脚本(告诉系统你要干什么、需要多少资源)→ 提交排队(sbatch/qsub)→ 查看结果(squeue/sacct + 输出文件)。不要在登录节点跑大任务,不要申请远超实际需求的资源,这是集群使用的两条基本礼仪。