cellranger countがメモリ不足で止まる場合の対処方法

日付;2024/12/7(土)、2024/12/10(火)SWAPパーティションの導入によりSWAPが動くようになった。、2024/12/12(木)結局キャシュの定期クリアを設定する。

はじめに

最近、新しいPCでcellranger 9.0.0を使い出した。cellranger 9.0.0には、新しくcellranger anniotateが加わったらしい。この機能を使用するためには登録が必要で、なんか面倒なのでまだ試したことはない。有用であるため実装されたのであろうが、果たしてどうなんだろうか。論文に「細胞のタイピングはcellranger annotateを行った。」とか書くだろうか。「cellranger count とannotateでそれぞれマッピングと細胞のアノテーションをそれぞれ行い、次に次元削減の後にcelltypistとマニュアルで細胞のタイピングを行った。」みたいに、参考程度になるんじゃあないだろうか。一般的にシングルセルRNAシークエンスでは、tSNEやuMAPで次元削減をする前にRNAやrRNAと思われるカウントを除去したり、ダブレットを除去したりするわけだが、それ無しにタイピングまで行うというのが良いのかどうなのかよくわからない。それともこのcellranger annotateという機能はそういったQCのステップまでやってくれるのだろうか。計算方法や使用しているデータセットが信頼できそうなものならば、かなり便利だと思う。

version 8.0.1との違いはnampyのバージョンが上がったことくらいであり、そんなに大きく変わった気はしない。自分はnumpyのバージョン違い(だったのかどうかはわからんのだが…)でエラい目にあったことがあるので、なんとも油断できないと思うのだが….

そのcellrangerを使っていて問題が起こった。どうやら、キャシュ不足でcellranger countの途中で落ちてしまうらしい。その問題を解決するのに、約1週間(追加で3日@2024/12/10(火))もかけてしまった。そして、一応対策は立てることが出来、cellranger countも完了できるようになったが、根本的にこの問題が解決されていないように思う(2024/12/10(火)に解決済)。以下はcellranger用に対策したことではあるが、別にcellrangerだけに限ったことではない。他の解析で同様のことが起こる場合にも使用できると思う。

コンピューターは、CPUがRyzen 9 9950X、RAMが128GB、SWAPとしていつものように1TBのswap fileを設定している。この手の解析をしているとRAMを使い果たしてSWAPを350GB、つまり、500GBは使うことがわかっているためである。コンピューターの詳しい構成はここに記した

cellrangerがキャッシュ不足で落ちる

問題は、cellranger countでのマッピング中(おそらくSTARによるマッピングだと思うが、詳しく調べてないので定かではない。)に、とどのつまり、メモリリークのよう状態で止まってしまうことである。メモリのキャッシュ領域が一杯になるとプログラムが落ちてしまうようだ。逐次出力される_logを見てもエラーは起こっていないらしいので、本当に「落ちた」って感じだろう。

おそらくこのPCのシステムとしての問題が原因だと思う。cellrangerのエラー以外で落ちているためか、キャッシュに保存されているデータがそのまま残ってしまっているらしい。つまり、不要になったデータがキャッシュにそのままずーっと保存されてしまっている。さらに、もう一つの問題はSWAPである。おそらくSWAPがうまく使われていない(おそらくこれが主な原因だった。どうやらswap fileへの書き込みが止まってしまい、そこで落ちているようだった。swap partitionにしたら過剰分がSWAPに流れるようになった。このSWAP問題は2024/12/10(火)に解決済)。一応使っているようだが、それこそあまり関係ないプロセスを優先的にSWAPに送っているようで、メインで使用しているプロセス、つまりcellrangerには優先的にメモリを使用するように動いているようだ。以前Mouse K5でチマチマとマッピングしている時はこれは起こらなかったのだが、今回はそれが起こりまくる。なんとかしなければならない。core i9とかだったらこの問題は起こらないのだろうか。いや、でもなんかintelのCPUは嫌だ。それは以前書いた通り。

本当に、なんで落ちるんだろうか(2024/12/10(火)に解決済)。ということで、以下が今回使った解決策である。以下の対策で落ちずにプログラムが完了するってことは、やっぱりメモリ不足なんだろう。

ログを見ている限りでは、これはmouse K5でも起こっていた。ということは、キャッシュのクリアがうまく行っていないようだ。何がwating for jobs to completeだ。全然待ってないやんか。ちなみに、一応cellranger 8.0.1も同じPCで使ってみたけど、やっぱり起きた。システムの問題らしい。なぜかよくわからん(2024/12/10(火)に解決済)

ここにメモリの設定について詳しく書いてあるので、これからちゃんと読んでコンピューターをチューニングする必要がある。とりあえず、今はニワカで設定する。

SWAPの優先度を上げる

今後のためにも、まずはSWAPの使用頻度を上げようと思う。一般的な用度であればこんなことをする必要がないが、特にR で大きなデータセットを使う場合なんかはSWAPが必須と思う。Rこそがメモリ喰いである。それに、言うても機器は消耗してしまうのだが、昨今ではm.2は体感的にも処理速度が比較的速いこともあり、これを使わない手はないと思っている。

結局のところ、これではcellrangerが落ちるのを阻止することはできなかった。しかし、設定しておいて損はないだろうと思う。以下で対処する。これは、恒久的に設定する場合である。

1.SWAPを頻繁に使うようにする。

SWAPの設定については別にポストしている。ここは設定の変更方法について記す。まず、geditでsysctl.confを開く

Bash
sudo gedit /etc/sysctl.conf

そして、一番下にvm.swappiness=100を追記して保存し、geditを閉じる。この値、0だとなるべく使わない、100だと頻繁に使う、という意味らしい。デフォルトが60。この値が高すぎるのは非推奨だって。

Plaintext
vm.swappiness=100

そして、以下により一応有効にする。不安だったらsudo rebootで再起動させてしまえばよい。

Bash
sudo sysctl -p

以下でも良いらしいが、これは一時的に変えるだけらしい。正直、これでも良いように思うが、自分はSWAPを最大限使ってしまいたいので上記のように設定ファイルに書き込んでしまった。

Bash
sudo sysctl vm.swappiness=100
sudo sysctl -p

2.SWAPのプライオリティーを上げる。

これもデータをSWAPに移動させるかどうかの優先度を設定するところのようだ。まず、SWAPをoffにして、SWAPの設定のときと同じようにgeditでfstabを開く。

Bash
sudo swapoff -a
sudo gedit /etc/fstab

fstabが開いたら以下を入れる。もし”/swapfile none swap defaults 0 0″となっていたら、defaultsの部分をsw,pri=32767にする。これが最大値で、デフォルトが-2らしい。今回初めて気がついたのだが、swapファイルを使う場合は2列目はnoneにしなければならないようだ。自分はこれまで、ずっとswapと入れて使っていたが、これでも問題なかった。以下に書き換えたらgeditを保存し、閉じる

Plaintext
/swapfile none swap sw,pri=32767 0 0

次に、以下でSWAPを有効にし、確認する。

Bash
sudo swapon --priority 32767 /swapfile
sudo swapon -a
sudo swapon --show

これでSWAPをより頻繁に使うようになったはず。上述の通り、これではcellrangerが落ちるのを阻止できず、次に述べるキャッシュの定期的なクリアのほうが明らかに有効だった。

定期的にキャッシュをクリアする

浅知恵の限り色々と試したが、最終的に、「定期的にキャッシュ領域をクリアする」という方法で落ち着いた。ある領域のマッピングが終わったらキャッシュをクリアように設定できれば一番良いのだが、そんなことを出来るまでのスキルは自分にはない。なので、力技を使う。

やったことは5分毎にキャッシュをクリアする、ってことである。こうすれば、ゴミ掃除しながプログラムを走らせることになるので、止まることはない。しかしながら、ディスクへ書き出してから消すステップが入るため、計算がかなり遅くなるようだ。ログをみていると、処理時間が3倍くらいに増えている可能性がある。でもいちいち止まられるよりは良い。

1.メモリをクリアするためのスクリプトを作る。

まずはclear_memory.shを作成する。内容はキャッシュをクリアするときのヤツである。

Bash
sudo gedit /usr/local/bin/clear_memory.sh

内容は以下の通り。syncを入れてキャッシュの内容を書き出さないと全部消えないらしい。参考にしたのはこのサイト。

Bash
sync; sudo echo 3 > /proc/sys/vm/drop_caches

保存して、パーミッション(全ユーザーに実行権限を与える)を与える。

Bash
sudo chmod +x /usr/local/bin/clear_memory.sh

2.作成したプログラムを定期的に走らせる。

次にvisudoをひらく。これもgeditで開く。sudoersという、誰に何をさせるか記述したファイルがあるらしいのだが、それを編集するためのコマンドがvisudoらしい。デフォルトではnanoで開かれてしまう。自分はviとか、nanoとか、emacsとか、よく分からんし、今後も覚える気は全くない。自分はgedit一択である。viとかemacsとかnanoとか、本当に必要ですか?国語における古典と漢文みたいな感じじゃあないですか?言うて、現代文だって大嫌いだけどな。

Bash
sudo EDITOR=gedit visudo

開いたら、以下を# Allow members of group sudo to execute any commandの下に追加して保存し、閉じる。これにより全ユーザーにパスワードなしで先ほど作ったclear_memory.shを実行できるようにする。これをやらないと、いちいちsudoでパスワードを入れなければならず、 cellranger中に夜も眠れなくなる。

Bash
# Allow members of group sudo to execute any command
ALL ALL=(ALL) NOPASSWD: /usr/local/bin/clear_memory.sh

次にTerminalで以下を入れる。crontabはスケジューラーのようだ。

Bash
sudo EDITOR=gedit crontab -e

テキストが開いたら一番下(いろいろとコメントアウトされているが、その一番下。)に以下を入れて、geditを保存する。相変わらずgedit。

Plaintext
*/5 * * * * /usr/local/bin/clear_memory.sh

次に、一応以下を流すことでちゃんと書かれていることを確認する。

Bash
sudo crontab -l

3.モニタする

上記1から3で記入したことがちゃんと実行されるかどうかを以下により確認する。

Bash
sudo tail -f /var/log/syslog

これを流しておいて、新しく別にTerminalを起動させてcellranger countをやってみると、今度は落ちずにプログラムを完了することができた。やれやれ。解決するまでにけっこう時間がかかってしまった。もったいない。もうMouse K5に戻そうかと、本気で思ったわ。

4.他に考慮するべきSWAP関連の値

SWAP関連は以下の値がおそらく関係するので、今後設定する必要がありそう。これらの最適値を探してsudo gedit /etc/sysctl.confに新しく値を書いて、sudo sysctl -pを流して、念の為にsudo rebootすれば良い。これらはここに書いてある。

Bash
# how to access to the value
cat /proc/sys/vm/dirty_ratio
cat /proc/sys/vm/dirty_background_ratio
cat /proc/sys/vm/overcommit_memory
cat /proc/sys/vm/overcommit_ratio
cat /proc/sys/vm/min_free_kbytes
Plaintext
# Following values are defaults.
vm.dirty_ratio=20
vm.dirty_background_ratio=10
vm.overcommit_memory=0
vm.overcommit_ratio=50
vm.min_free_kbytes=67584

2024/12/10(火)SWAPパーティションにしたらSWAP出来るようになった

上記の通り2024/12/10(火)まではSWAPを/swapfileに当てることにより運用していた。しかし、メモリがフルの状態になるとswapに以降とするのだが、ある一定量、高々5GBくらいまでswapfileに書き込んだ時点でエラーも何も吐き出さずに急にcellranger countが文字通り落ちてしまっていた。_logファイルにも何もなし。ただ一言「あと62GBのメモリが必要なので、待ってるで!!」と言ったきり、声も出さずに落ちていった…..!!!上記の設定値を色々と調整して、SWAPをより優先的に使用するように設定しても全く効果がない。そういうことなので、定期的なキャッシュ領域を5分毎にクリアすることによって騙しながらcellranger countを走らせていた。しかし、これは明らかに根本的な解決ではない。もし大量のキャッシュが必要で、かつ5分以上も時間のかかる計算があったら、そのままキャッシュがクリアできずにまた落ちてしまう。それに、tradeseqやssGSEA2といった、メモリ爆食の解析には到底耐えきれるものではない。どうしても解決する必要がある。

なので、cellranger countでPCをシバき上げ、その落ち方をじーっと見てたり、さらにstressコマンドを使った仮想メモリ、要はSWAPへの強制負荷なんかを見たりして色々と考えてみた。ちなみにstressコマンドでも何も言わずに黙って落ちる。その結果、swapfileへの書き込みが遅すぎるんじゃあないかという疑問が生じた。どうしてもswap fileへの書き込みで落ちている気がしてならない。

昨今、m.2 SSDにOSを当て、それよりも遅いSATA経由のドライブはストレージなどに優先的に割り当てている人が多いことと思う。さらにm.2も十分に大容量になってきており、今では1TBはかなり安くなり、2TBとかだって普通になってきていると思う。つまり、そういった一昔前に比べれば十分に早い記憶媒体を使っている以上、SWAPをファイル(swap file)に当てようがディスクのパーティションに当てようが(swap partition)そんなに速度的な差はないのではないだろうか。

そういうことで、swapfileではなく、SWAPパーティションを使うことにした。それもドライブを独立させた上での。本当はこのm.2は別の用途に使いたかったんだけど、これしかないんでしょうがない。試してみよう。以下は手順である。

1.SWAPをOFFにする

まずは、以前のポストにある通り、SWAPを切って、これまで使ってきたswapfileを消す

Bash
su
swapoff -v /swapfile
gedit /etc/fstab
# delete 
# "/swapfile swap swap defaults 0 0" or 
# "/swapfile	none	swap	sw,pri=32767	0	0", or  
# "/swapfile	swap	swap	sw,pri=32767	0	0" and
# then Save it. 
rm /swapfile

2.新しいディスクにパーティションを設定する

もしすでにパーティションが作成してある場合は、ここはスキップ出来る(と思う)。Ubuntu のディスクユーティリティーであるDisksでも作成できるので、別にターミナルから行う必要はない。

以下はターミナルから設定する場合である。

2.1.パーティション作成

最初にディスクは事前にunmountさせておく。

ディスクに設定されているパーティションを確認する。そうすると、今回設定するディスクは/dev/nvme1n1であり、そこには何もパーティションが設定されていないことがわかる。

次に、fdiskによりパーティションを設定する。sudo fdisk /dev/nvme1n1すると色々とよくわからんことを聞いてくるが、最初の Command (m for help):の後にnを、最後のCommand (m for help): の後にwを入力する以外はデフォルトで入れておいた。

Bash
# Check partation for every drive. 
lsblk
sudo fdisk /dev/nvme1n1
Command (m for help): n
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-4000797359, default 2048): 2048
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1000000-4000797359, default 4000797359): 4000797359
Command (m for help): w

この後、またlsblkでディスクのパーティションを確認してみると、先程設定したディスクの下にnvme1n1p1が出来ていた。今回はここにSWAPを設定しようと思う。以下を流す。途中のblkidはパーティションが割り当てられたかどうか確認するだけ。一応これも確認した方が良いと思う。

geditで/etc/fstabを開き、一番下に、/dev/nvme1n1p1 none swap sw 0 0を入力し、保存して閉じ、一度swapoff -aを流してswapを切って、もう一度swapon -aで有効にする。で、swapon –showで確認しておく。これで有効になっているはず。

2.2.SWAP パーティションの割当

Bash
lsblk
sudo mkswap /dev/nvme1n1p1
sudo swaplabel -L swap /dev/nvme1n1p1
sudo blkid
sudo swapon /dev/nvme1n1p1
sudo gedit /etc/fstab
# /dev/nvme1n1p1	none	swap	sw	0	0
sudo swapoff -a
sudo swapon -a
sudo swapon --show

最後に、うまくSWAPが動くかどうか、stressコマンドで仮想メモリ(SWAP)に負荷をかけてみる。というのも、これを設定している時点ですでにcellranger countは終了してしまっているためである。

2.3.メモリとSWAPへの強制負荷

Bash
stress --vm-bytes 500G --vm-keep -m 1

下の画像の通り、SWAPがうまく動きだした。stressコマンドでもcellranger countでも、SWAPファイルを使っているときはSWAP領域ではなくCacheにデータを入れて順次メモリに移しているようだったが、今回はメモリが圧迫されだしたらSWAPにデータを保存しているようだ。

もしSWAPでこんなにデータを食う解析を行うことになったら、PCの消耗が激しそうである。こういった高負荷の解析のためにこのコンピューターを買ったわけだが、なんか、あまり酷使しているとすぐにぶっ壊れそうで怖い。というか、SWAPに2TBって…さすがにこんなに要らんやろ。今度1TB買おう。

これで、ひとつ勉強になったことがある。それはswapfileよりもswap partitionの方が圧倒的に早い!!ということである。時代はm.2のPCI Express 5xとかなので、swap partitionだろうがswap fileだろうがあまり変わらないと思っていたし、それが一般的な理解だろうと思う。でも、場合に依ればswap partationの方が早いということがこれでわかった。とりあえず良かった。これでこのPCもフル活用できそう。後ほど5分毎のキャッシュクリアのスクリプトは消す必要がありそう。あれ、どこかで悪影響する気がしてならない。ということで、「2.作成したプログラムを定期的に走らせる。」でvisudoとcrontabに追記した内容、それぞれALL ALL=(ALL) NOPASSWD: /usr/local/bin/clear_memory.shと
*/5 * * * * /usr/local/bin/clear_memory.shをコメントアウトして、定期的なキャシュクリアのスクリプトが流れてしまわないようにしておいた。ただし、なにかに使えるかもしれない、というか、まさかcellranger countでは必要になってしまうかもしれないので、/usr/local/bin/clear_memory.shは2024/12/10(火)の時点では消さずに残しておいた。また考えるの面倒なので。

2024/12/12(木)結局このPCでcellranger countを使う場合は定期的なキャッシュクリアを行うことにした

SWAPパーティションを入れた後に何度かcellranger countを走らせてみたが、どうもキャッシュを上手く消せていないように思う。結局、ニワカで入れた5分毎のキャシュ消去が一番有効だったらしい。このあたりを上手く設定しないと今後もメモリ爆食いライブラリで止まる可能性がある。これはなんとかシないといけない…

ということで、章題通り、cellranger countでは5分毎のキャッシュクリアを行うことにした。結局、SWAP問題は解決してもキャッシュ問題は解決出来ていないって感じである。どうなっとんねん。

メモリ監視のためのコマンド

以下がメモリの状態を監視するコマンドである。メモリが原因で起こるエラーかと思ったら、このあたりで監視すれば良いのではないかと思う。

目的コマンド
仮想メモリの設定に関する値一覧ls /proc/sys/vm/
イベントのログsudo tail -f /var/log/syslog
メモリの監視vmstat 1
メモリの監視watch -n 1 free -h

思うこと

cellrangerはSTARを使っており、このcellrager落ちはSTARが落ちるのが原因だろうと思っている。なんかもう懐かしいわ、STARが落ちてなんでやねんってなるの。これって、AMDのCPUで起こることなんだろうかSWAP問題は2024/12/10(火)に解決済。なんかそんな気がしてきた。なぜかというと、cellragerのインストラクションに、「Intelならば8コア以上、AMDならば64コア以上」と言うSystem Requirementが書いてある。64コア以上って、Threadripperよな。Threadripperって、TDP(Total Design Power; 要は消費電力)が350Wとかそういう値だったと思う。Ryzen 9 9950Xの2倍程度の消費電力である。言うて2倍か…型落ちのThreadripperを使うっていう手もあったか….なんか損した気分。

とにかく、この5分毎にキャッシュをクリアするのは、自分の現PCにとっては有効だった。この必要がない場合は、mouse K5でチマチマ解析していたときの20倍くらい計算速い可能性があるんだけど….これで約2から6倍程度か….なんか釈然とせん(SWAP問題は2024/12/10(火)に解決済)

以前から感じることであるが、今後、研究に使えるだけのゲノムや遺伝子発現の解析は、個人のリソースでは難しくなる時代が来るような気がしてきた。その場合は本気で大きなコンピューターやサーバーを常用する必要が出てくるのではないか思う。当然ハードウェア側もどんどん発展しているが、ソフトの開発や情報量の増加に追いついていない、みたいなことが、専門としないエンドユーザー側で起こるんじゃあないだろうかと、ちょっと不安である。学ぶのを止めてしまったら終わりって感じである。