magattacaのブログ

日付以外誤報

メモリの節約でColaboratoryの壁を越えようとする話

先の記事でGoogle colaboratoryの制限により、大きなファイルの処理ができなかったという結果になりました。

「先にMolオブジェクトをまとめて作るのではなくてforの中で一つずつ作ればメモリの節約にはなる」と教えていただいたので早速試してみたいと思います。 @yamasasaKit_先生ありがとうございました!

処理としては先の記事のままで、sdfファイルの読み込み以降の操作が異なります。

Google colaboratoryで諸々準備をした後に以下を実行しました。

#必要なモジュールの読み込み
from rdkit import Chem
import gzip
from rdkit.Chem import MolStandardize

#Googleドライブから取ってきた圧縮ファイルの読み込み
EPc_gz = gzip.open('Enamine_Premium_collection.sdf.gz')

今回もFowardSDMolSupplierで読み込みますが、Molオブジェクトをforの中でつくるため、リスト内包表記にはいれません。(←前回との違い)

#ForwardSDMolSupplierで読み込む。まだMolオブジェクトのリストにしない。
EPc_suppl = Chem.ForwardSDMolSupplier(EPc_gz)  

それでは脱塩処理してMolオブジェクトのリストを作成します。 時間も測ってみます。

%%time

#molオブジェクトのリストを作る段階で前処理を実行してメモリを節約する。
#空のリストを作成

EPc_mols_pro = []

#ループ!!!
for x in EPc_suppl:
  if x is not None:
    mol = x
  
  #構造の標準化
  normalizer =MolStandardize.normalize.Normalizer()
  mol_norm = normalizer.normalize(mol)
  
  #一番大きいサイズのフラグメントのみ残す
  lfc = MolStandardize.fragment.LargestFragmentChooser()
  mol_desalt = lfc.choose(mol_norm)
  
  #電荷の中和
  uc = MolStandardize.charge.Uncharger()
  mol_neu = uc.uncharge(mol_desalt)
  
  #新しいリストに追加
  EPc_mols_pro.append(mol_neu)

かかった時間・・・

CPU times: user 3min 37s, sys: 12.5 s, total: 3min 50s Wall time: 3min 50s

ここまでの「使用したRAM 1.85GB」でした。

念のため処理できた数を確認して見ます。

len(EPc_mols_pro)

「128816」とでました。前回も「128816」だったので、同じ数だけできているようです。

一応出力して、ローカルで確認します。

#構造とidnumberのみを残したsdfファイルを作成
writer = Chem.SDWriter('Enamine_Premium_collection_processed_2.sdf')
writer.SetProps(['idnumber'])        #(01/14)追記 SetPropsの引数をリストに変更
for mol in EPc_mols_pro:
  writer.write(mol)
writer.close()

#圧縮して出力
!gzip -c Enamine_Premium_collection_processed_2.sdf > Enamine_Premium_collection_processed_2.sdf.gz

upload_file = drive.CreateFile()
upload_file.SetContentFile('Enamine_Premium_collection_processed_2.sdf.gz')
upload_file.Upload()

出力まで行って、「使用したRAM 1.92GB」。前回は「3.91GB」だったので、約半分です。 Molオブジェクトのリストを2回作っていたのが、1回になったからでしょうか?

まさかこんなに簡単にメモリの節約ができるとは・・・・。

ちなみに自分のPCでsdfを確認すると前回と同じような構造が出ていました。

f:id:magattaca:20190114122649p:plain

) 上の図は修正前のものです。見た目は変わってしまいますが、こちらの方がわかりやすいので残しておきます。

より大きなファイルで同じ処理をした結果は以下の通り。
ファイルごとにセッションを新しくして実行しています。

Enamine_Advanced_collectionの場合

  • 処理の時間 CPU times: user 13min 27s, sys: 54.8 s, total: 14min 22s Wall time: 14min 22s
  • 化合物総数 486322
  • 全体のメモリ 6.21GB

UOS_HTS_collectionの場合

  • 処理の時間 CPU times: user 15min 17s, sys: 54.5 s, total: 16min 11s Wall time: 16min 12s
  • 化合物総数 516664
  • 全体のメモリ 7.34GB

Enamine_HTS_collectionの場合

残念ながら最後まで至らず・・・ファイルサイズがEnamine_Advanced_collectionの5倍くらいあるので仕方ないかもしれません。

私のパソコンでやると総数「1921120」でした。

創薬ちゃんさんによると、ライブラリの構成は以下のようになっているそうです。

About 2.5 million・・・・ここからどう絞り込めば・・・