FASTQ 无损压缩#
fqzip 把 FASTQ 压缩成 .bzfq 归档(下一个发布包起提供)。解压得到的文本与原始 FASTQ 逐字节相同:read 名称、+ 行、换行符(包括 CRLF)都原样保留;输入是 .gz 时,还原的是解压后的 FASTQ 文本。不符合 FASTQ 格式的内容也能存入(按普通文本压缩)。同一输入在任何线程数下生成的归档完全相同(参考模式在 CPU 上运行且内存紧张时例外,见两种模式)。
归档可以直接作为 fastq2bam / align 的输入,不必先解压,见直接作为比对的输入。全部参数见工具参考。
开发中
归档格式在正式发布前仍可能变化。在此之前生成的归档,请用生成它的同一版本解压。
快速开始#
有参考基因组时,reads 以在参考基因组上的位置和差异保存。参考基因组旁需要有 bwa 索引(baizegen index),解压时需要同一个参考基因组:
baizegen fqzip -t 32 --ref Homo_sapiens_assembly38.fasta -o sample.bzfq sample_R1.fastq.gz sample_R2.fastq.gz
baizegen fqzip -d -t 32 --ref Homo_sapiens_assembly38.fasta -o sample_R1.fastq -o sample_R2.fastq sample.bzfq
GPU 版(baizegen-gpu)加 --device gpu,由 GPU 把 reads 定位到参考基因组上,压缩更快。解压只用 CPU,命令相同:
baizegen-gpu fqzip -t 32 --device gpu --ref Homo_sapiens_assembly38.fasta -o sample.bzfq sample_R1.fastq.gz sample_R2.fastq.gz
没有参考基因组时(或者不方便携带参考基因组)用 --pseudo,解压不需要任何其他文件:
baizegen fqzip -t 32 --pseudo -o sample.bzfq sample_R1.fastq.gz sample_R2.fastq.gz
baizegen fqzip -d -t 32 -o sample_R1.fastq -o sample_R2.fastq sample.bzfq
只检查归档能否完整解压(核对每个数据块的 CRC),不写出文件:
baizegen fqzip --test -t 32 --ref Homo_sapiens_assembly38.fasta sample.bzfq
输入一个 FASTQ 为单端(或交错的双端),两个为双端;解压时每个文件给一个 -o,顺序与压缩时相同。
两种模式#
参考模式(--ref) |
无参考模式(--pseudo) |
|
|---|---|---|
| 原理 | 每条 read 存为它在参考基因组上的位置、CIGAR 和与参考不同的碱基;定位不上的 read 用上下文模型压缩 | 先由 reads 拼出一套序列(伪基因组)随归档保存,reads 再以在它上面的位置和差异保存 |
| 压缩需要 | 参考 FASTA 和它旁边的 bwa 索引 | 只需 FASTQ |
| 解压需要 | 同一个参考 FASTA(逐条核对 contig 的名称、长度和 MD5) | 只需归档 |
| 归档大小 | 最小 | 比参考模式大约 13 % |
| 速度 | 压缩快(尤其 --device gpu) |
压缩较慢(先要拼出伪基因组);解压与参考模式相近 |
参考模式在 CPU 上先用参考基因组的 k-mer 索引定位大部分 reads,其余交给 bwa。k-mer 索引的密度按扣除各线程所需之后的可用内存选择(内存不够时全部交给 bwa),因此内存紧张时,不同的内存条件或线程数生成的归档字节可能不同,但解压结果都与原始 FASTQ 相同。--device gpu 时所有 reads 都由 GPU 上的 bwa 定位,归档与内存和线程数都无关。
压缩级别#
--level 改变质量值的编码,以及参考模式下 read 与参考基因组之间差异的编码;read 名称等的编码在各级别相同。默认是最快的 1 级。任何级别的归档都用同一条命令解压。
| 级别 | 质量值编码 | 与参考的差异 | 特点 |
|---|---|---|---|
--level 1(默认) |
fqzcomp 质量值模型(htscodecs) | 每条 read 一个差异列表:解压时复制参考序列,再改写少数不同的碱基 | 压缩和解压最快 |
--level 2 |
上下文混合模型(精简版) | 逐个碱基判断是否与参考不同 | 介于两者之间 |
--level 3(--best) |
上下文混合模型 | 逐个碱基判断是否与参考不同 | 归档最小,压缩和解压都最慢 |
级别之间的差别取决于质量值是否经过分档。质量值分档的数据(NovaSeq、HiSeq X 等,只有几个不同的质量值),--level 3 的归档比默认的 1 级小约 2–6 %(下面性能一节的全基因组样本:2.0 %);质量值未分档的数据差别更大,在我们的测试数据上 HiSeq 2000 小 9.7–10.9 %,MGI 小 7.5 %。存档空间比压缩时间更重要时,对这类数据建议用 --best。
直接作为比对的输入#
fastq2bam 和 align 用 bwa 引擎(--engine bwa 或 --engine bwa-gpu)时,可以把一个 .bzfq 归档放在 FASTQ 的位置;包含两个文件的归档按双端处理:
baizegen-gpu fastq2bam -R Homo_sapiens_assembly38.fasta --engine bwa-gpu -t 32 --rg '@RG\tID:sample\tSM:sample\tPL:ILLUMINA' -O sample.bam sample.bzfq
归档在同一个进程中边解压边比对,不写出中间的 FASTQ。输出的 BAM 与先解压、再对 FASTQ 运行同一命令的结果逐字节相同。参考模式的归档按比对用的 bwa 索引解压,不再读取 FASTA,归档的 contig 名称和长度须与索引相同(每个数据块的 CRC 照常核对)。不能与 --fastp 同时使用;默认的 minibwa 引擎不读取归档。
解压归档比解压 gzip 需要更多 CPU 和内存。下面性能一节的样本在机器 A 上运行 fastq2bam --engine bwa-gpu -t 48:读入 .fastq.gz 48.2 秒、峰值内存 17.0 GB;读入 1 级归档 49.6 秒、30.7 GB;两者的 BAM 逐字节相同。
内存#
内存占用与线程数和数据块大小大致成正比:每个线程同时处理一个数据块(默认每个文件 50 万条 reads),压缩时还在处理队列中保留几个数据块。需要减少内存时:
- 用
-b 250000把数据块减半,内存减少约 25 %,归档大约大 0.9 %; - 减少线程数;
- 用
--max-memory SIZE(所有命令通用,见内存)限制本次运行的内存,fqzip据此减少同时工作的线程数。
参考模式在 CPU 上运行时,人类参考基因组的 k-mer 索引另外需要约 7 GB(内存不够时自动改为全部交给 bwa)。
性能#
SRR9613620(NovaSeq 6000 人类全基因组,4,930 万对 2 × 150 bp reads,FASTQ 文本 33.1 GB)。所有程序在同一台机器上运行(机器 A:AMD Threadripper 3960X 24 核 48 线程,1 × RTX 5090),各用 48 线程,输入和参考基因组事先拷到本地 NVMe 硬盘(拷贝不计时),每项运行一次。解压都写出文件到本地硬盘,并核对与原始 FASTQ 逐字节相同。fqzip 和 Spring 读入 .fastq.gz,pigz 和 zstd 读入 FASTQ 文本。
| 程序 | 文件大小 | 压缩比 | 压缩 | 解压 | 峰值内存(压缩 / 解压) |
|---|---|---|---|---|---|
gzip(pigz 2.8,-6) |
6,722.5 MB | 4.9 | 51.9 秒 | 66.5 秒 | < 0.1 GB |
zstd 1.5.5(-3) |
6,923.4 MB | 4.8 | 18.0 秒 | 40.0 秒 | 0.5 GB |
| Spring 1.1.1 | 1,095.3 MB | 30.2 | 385.9 秒 | 104.0 秒 | 17.0 / 18.8 GB |
| DRAGEN ORA | 1,068.5 MB(1,019 MiB) | 31.0 | — | — | — |
fqzip --ref,1 级(默认) |
917.7 MB | 36.1 | 187.7 秒 | 42.7 秒 | 35.4 / 20.2 GB |
fqzip --ref,2 级 |
909.7 MB | 36.4 | 219.5 秒 | 86.5 秒 | 41.5 / 19.0 GB |
fqzip --ref,3 级(--best) |
899.7 MB | 36.8 | 287.2 秒 | 188.1 秒 | 49.5 / 23.7 GB |
fqzip --pseudo,1 级 |
1,037.0 MB | 31.9 | 440.6 秒 | 48.7 秒 | 38.5 / 19.7 GB |
fqzip --pseudo,3 级 |
1,019.5 MB | 32.5 | 617.3 秒 | 208.2 秒 | 51.1 / 23.7 GB |
压缩比 = FASTQ 文本大小 ÷ 压缩后大小。说明:
- fqzip 参考模式的压缩用
--device gpu(GPU 定位 reads,其余在 CPU 上);所有解压都只用 CPU。Spring、pigz、zstd 只用 CPU。 - DRAGEN ORA 一行是 Illumina 公布的同一数据(SRR9613620,按 MiB 计)的压缩后大小,见 Illumina 文章 "Design considerations and methodology of .ORA format";我们没有运行 ORA,所以没有它的速度和内存数字。ORA 解压同样需要参考基因组。
- pigz 和 zstd 解压一个文件基本只用一个线程。
- 这一样本的质量值是 NovaSeq 的分档质量值。质量值未分档的数据上,1 级与 3 级的差别更大,见压缩级别。
- fqzip 的内存比 Spring 高,主要随线程数增长,见内存。