Skip to content

EXARTeo/Remote-Homology-Search-with-Approximate-Methods-ESM-2

Repository files navigation

Αναζήτηση Απομακρυσμένων Ομολόγων με Προσεγγιστικές Μεθόδους & ESM-2

1. Περιγραφή

Το έργο υλοποιεί pipeline δύο φάσεων για εντοπισμό πιθανών remote homologs (“Twilight Zone”, <30% sequence identity) συνδυάζοντας:

  1. ESM-2 embeddings: μετατροπή πρωτεϊνικών ακολουθιών (FASTA) σε διανύσματα σταθερού μεγέθους (mean pooling).
  2. ANN αναζήτηση (Approximate Nearest Neighbors) και πειραματική σύγκριση απέναντι σε BLAST: Euclidean LSH, Hypercube, IVF-Flat, IVF-PQ, Neural LSH, και (προαιρετικά) brute force baseline.

Παραδοτέα “εκτελέσιμα” (όπως ζητάει η εκφώνηση):

  • Generating Embeddings: Generating_Embeddings/protein_embed.py
  • Search Benchmark: Search_Benchmark/protein_search.py

2. Δομή Project

Το project root έχει την παρακάτω δομή:

<project-root>/
├── bio_data/
├── black_box/
├── blast_out/
├── Common/
├── data/
├── embed_data/
├── Generating_Embeddings/
├── Nearest-Neighbors/
├── Neural-LSH/
├── scripts/
├── Search_Benchmark/
├── test_results/
├── test_summary/
├── requirements.txt
├── results_average.txt
├── results.txt
├── run_bench_grid.py
└── search_preparation.sh

bio_data/

Περιέχει UniProt/SwissProt/InterPro metadata (TSV) που χρησιμοποιούνται για bio comments (Pfam, GO, EC number, InterPro). Χρησιμεύει στη “βιολογική αξιολόγηση” των υποψηφίων remote homologs: όταν το BLAST identity είναι χαμηλό, το πρόγραμμα μπορεί να σχολιάσει αν υπάρχουν κοινά Pfam/GO/EC/InterPro στοιχεία.

Περιλαμβάνει και βοηθητικά scripts προετοιμασίας:

  • THE_MERGER.py (merge GO+InterPro σε annot TSV). Κάνει merge όλα τα "UniPro"/"Bio-annot" με “Gene Ontology IDs” και “InterPro” από ένα GO/InterPro TSV σε ένα annotation TSV, ώστε το bio_comment.py να έχει όλα τα πεδία ενιαία.
  • filter_tsv.py (φιλτράρισμα μεγάλων TSV ώστε να κρατάμε μόνο accessions που υπάρχουν στο dataset/queries)

black_box/

“Σημείο ολοκλήρωσης” με εξωτερικά binaries/indices:

  • Το compiled εκτελέσιμο search (από Nearest-Neighbors/) αντιγράφεται εδώ και καλείται από το protein_search.py για LSH/Hypercube/IVF-Flat/IVF-PQ.
  • Τα Neural-LSH indices αποθηκεύονται επίσης εδώ (π.χ. black_box/nlsh_model/).

blast_out/

Αποθηκεύει BLAST artifacts:

  • BLAST database prefix (π.χ. blast_out/swissprot_db.*)
  • Χρειάζεται γιατί το protein_search.py τρέχει BLAST ως reference baseline (Top-N hits) και υπολογίζει Recall@N.

Common/

Κοινά modules που χρησιμοποιούνται από embed & search:

read_fasta.py :

Διαβάζει FASTA και επιστρέφει λίστα από (header/id, sequence), με “καθαρισμό” γραμμών/κενών και σωστό χειρισμό πολλαπλών records.

load_model.py

Φορτώνει το μοντέλο ESM-2 και επιστρέφει έτοιμα αντικείμενα για inference: (model, batch_converter)

esm_embed.py

Υλοποιεί το “embedding pipeline”: batching → forward pass → εξαγωγή representations (π.χ. layer 6) → mean pooling στα residue tokens (χωρίς CLS/EOS/PAD) → αποθήκευση σε SIFT/fvecs binary format.

load_data.py

Loader για dataset σε SIFT/fvecs format (binary: [int32 d] + d float32 ανά vector) και το επιστρέφει ως numpy.ndarray τύπου (N, D).

brute_force.py

Brute force kNN baseline (L2/Euclidean) πάνω σε embeddings: για κάθε query βρίσκει τους top-k γείτονες με πλήρη σάρωση του dataset και επιστρέφει/γράφει αποτελέσματα σε format συμβατό με το report. Το χρησιμοποιειούμε στο Search Benchmark ως baseline/για έλεγχο ορθότητας.

data/

Είσοδοι (inputs):

  • dataset FASTA (π.χ. swissprot_50k.fasta ή αντίστοιχο)
  • query FASTA (π.χ. targets.fasta)

embed_data/

Outputs από τη φάση embeddings:

  • embedded vectors file σε SIFT/fvecs format (π.χ. dataset.dat)
  • ids mapping file (γραμμή i → protein accession/id)

Σημείωση: το protein_embed.py γράφει σε embed_data/dataset_ids.txt

Generating_Embeddings/

Το σενάριο παραγωγής embeddings:

  • protein_embed.py (main) — Υλοποιεί το πρώτο στάδιο του pipeline, όπου μετατρέπουμε το σωστό dataset FASTA (δηλαδή το σύνολο αναφοράς πάνω στο οποίο θα γίνει αργότερα η αναζήτηση) σε ESM-2 embeddings και τα αποθηκεύουμε σε αρχείο vector-format (π.χ. embed_data/dataset.dat) μαζί με το αντίστοιχο mapping IDs, ώστε το Search Benchmark να μπορεί να εκτελέσει ANN/BLAST συγκρίσεις πάνω σε ακριβώς αυτό το σταθερό embedded dataset.
  • embed_args.py (CLI args)

Nearest-Neighbors/

Κώδικας/εργαλεία από 1η εργασία (C++/Make) που παράγουν το executable search για Euclidean LSH / Hypercube / IVF-Flat / IVF-PQ σε “SIFT-like” μορφή. Η προετοιμασία γίνεται μέσω του search_preparation.sh, το οποίο τρέχει make στον φάκελο Nearest-Neighbors/ και στη συνέχεια μεταφέρει/αντιγράφει το παραγόμενο εκτελέσιμο search στο σωστό runtime directory black_box/ (δηλ. black_box/search) ώστε να μπορεί να κληθεί απευθείας από το Search_Benchmark/protein_search.py. Επιπλέον, έγιναν στοχευμένες αλλαγές στον κώδικα των IVF υλοποιήσεων και στο output interface:

  1. Optimizations σε IVFFlat και IVFPQ (speed-up): Όπως στη μετάβαση του IVFFlat από την Εργασία 1 → Εργασία 2, βελτιστοποιήσαμε τον υπολογισμό αποστάσεων και εδώ ώστε να είναι ταχύτερος. Συγκεκριμένα, στον IVFFlat (και κατ’ αναλογία στον IVFPQ) αντικαταστήσαμε την κλασική lp_dist με fast_dist, αποφεύγοντας περιττές sqrt πράξεις (δηλαδή δουλεύουμε με squared distances όπου είναι δυνατό), μειώνοντας αισθητά το κόστος ανά query.

  2. Αλλαγή output format (stdout αντί για κάποιο results.txt): Το search καλείται από το κύριο πρόγραμμα protein_search.py μέσω subprocess(). Για μεγαλύτερη αμεσότητα και ευκολία στο integration, αλλάξαμε το output του search ώστε να γράφεται στο stdout. Έτσι το protein_search.py μπορεί να διαβάζει άμεσα το output stream και να κάνει το αντίστοιχο parsing. Παράλληλα, αφαιρέσαμε περιττές πληροφορίες από την έξοδο (π.χ. το όνομα του αλγορίθμου στην αρχή) ώστε το format να είναι πιο “καθαρό” και σταθερό για parsing.

Neural-LSH/

Κώδικας από τη 2η εργασία (Neural LSH pipeline), ο οποίος χρησιμοποιείται για την ANN μέθοδο neural. Για να είναι λειτουργικό το υποσύστημα, απαιτείται build του βοηθητικού component στο Neural-LSH/IVFFlat_build_knn/ (δημιουργία του approx kNN graph που αξιοποιείται στο Neural-LSH), και αυτό το αναλαμβάνει επίσης το search_preparation.sh, το οποίο μπαίνει στον συγκεκριμένο φάκελο και εκτελεί make.

Επιπλέον, για λόγους ενοποίησης με το benchmark pipeline, κάναμε και εδώ τις ίδιες αλλαγές στο output format που εφαρμόσαμε στο Nearest-Neighbors: το output παράγεται στο stdout (όχι σε ενδιάμεσο αρχείο τύπου results.txt) και έχει “καθαρό”/σταθερό format χωρίς περιττά headers (π.χ. αφαίρεση ονόματος αλγορίθμου στην αρχή), ώστε το Search_Benchmark/protein_search.py να μπορεί να το διαβάζει άμεσα μέσω subprocess() και να κάνει το parsing με τον ίδιο ακριβώς τρόπο.

Search_Benchmark/

  • protein_search.py (main pipeline) — Κάνει embed τα queries on-the-fly, καλεί τις ANN μεθόδους (μέσω subprocess() προς black_box/search ή Neural-LSH scripts), τρέχει BLAST ως reference και στο τέλος παράγει ενιαίο report (χρόνοι/QPS, Recall@N, top-N hits, bio comments).
  • search_args.py (CLI args + defaults + hyperparameters) — Κεντρικός ορισμός όλων των CLI ορισμάτων και defaults· περιλαμβάνει και method-specific υπερπαραμέτρους (LSH/Hypercube/IVF/Neural) ώστε να μπορούμε να κάνουμε εύκολα benchmarking και grid runs.
  • blast.py (run + parse BLAST) — Αναλαμβάνει την εκτέλεση BLAST (και makeblastdb όπου χρειάζεται) και κάνει parsing των hits σε δομή που χρησιμοποιείται για Recall@N και για identity-based σύγκριση ανά query.

Σημείωση: Τα αρχεία που χειρίζεται πρέπει να είναι μέσα στο directory blast_out/

  • search_report.py (parsing ANN stdout outputs + Recall@N + report formatting) — Κάνει parsing του stdout από τα ANN runs (σταθερό format), υπολογίζει Recall@N έναντι BLAST Top-N και γράφει το τελικό report σε αναγνώσιμη/συγκρίσιμη μορφή.
  • bio_comment.py (UniProt maps + “Remote homolog?” comments) — Φορτώνει BIO-data maps (Pfam/GO/EC/InterPro όπου υπάρχουν) και προσθέτει ερμηνευτικά σχόλια ειδικά όταν το BLAST identity είναι χαμηλό ή απουσιάζει (υποψία remote homolog).

test_results/ και test_summary/

Φάκελοι για μαζικά πειράματα/αναζητήσεις (grid runs):

  • test_results/: αποθήκευση των “results reports” ανά run
  • test_summary/: αποθήκευση stdout/stderr/metadata ανά run

(Το run_bench_grid.py έχει τα παραπάνω directories ως default προορισμούς των αποτελεσμάτων του.)

scripts/

  • summarize_grid.py: Διαβάζει όλα τα *_summary.txt από το test_summary/, εξάγει για κάθε run τα metrics (avg recall@N, QPS), τα params και τον χρόνο, και φτιάχνει συγκεντρωτικό CSV test_summary/grid_results_summary.csv. Επιπλέον παράγει βασικά plots στο test_summary/plots/ (QPS vs Recall).

  • pick_best_configs.py: Παίρνει ως είσοδο το παραπάνω CSV και τυπώνει “καλύτερες” ρυθμίσεις ανά μέθοδο και συνολικά: (1) μέγιστο Recall, (2) μέγιστο QPS, (3) μέγιστο QPS υπό κατώφλι Recall, (4) “all-around best” με ένα dominance score.

  • csv_to_latex.py: Μετατρέπει το grid_results_summary.csv σε έτοιμους \LaTeX{} πίνακες (ένας ανά μέθοδο) και γράφει το αρχείο test_summary/grid_results_tables.tex.

Root επίπεδο

  • search_preparation.sh
    Script προετοιμασίας/build που αυτοματοποιεί το setup των εξωτερικών εκτελέσιμων

  • run_bench_grid.py Grid/benchmark runner που εκτελεί μαζικά το Search_Benchmark/protein_search.py για πολλές μεθόδους και συνδυασμούς υπερπαραμέτρων (σύμφωνα με προ-ορισμένα grids), δημιουργώντας ξεχωριστά αρχεία αποτελεσμάτων (test_results/) και αναλυτικά summaries με stdout/stderr/χρόνους/return codes (test_summary/) για εύκολη σύγκριση runs.

  • results.txt Τα αποτελέσματα των καλύτερων εκτελέσεων

  • results_average.txt Ο μέσος όρος των τιμών αυτών των καλύτερων αποτελεσμάτων


4. Εγκατάσταση εξαρτήσεων

4.1 Προαπαιτούμενα συστήματος

  • Linux, Python 3.10+
  • build tools: make, C/C++ compiler
  • NCBI BLAST+ (απαραίτητο για το reference BLAST κομμάτι)

Εγκατάσταση BLAST+ (Ubuntu/Debian):

sudo apt update
sudo apt install ncbi-blast+

4.2 Python environment (venv)

Από <project-root>:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

4.3 Εγκατάσταση Python packages

Εγκαταστήστε τις απαραίτητες βιβλιοθήκες:

pip install numpy
pip install torch --index-url https://download.pytorch.org/whl/cu121
pip install fair-esm
pip install scikit-learn
pip install kahip

ή

pip install -r requirements.txt

5. Build εξωτερικών εκτελέσιμων (Nearest-Neighbors & Neural-LSH helper)

Πριν την εκτέλεση του search benchmark για LSH/Hypercube/IVF-Flat/IVF-PQ, πρέπει να υπάρχει το executable black_box/search.

Από <project-root>:

bash search_preparation.sh

Το script:

  • κάνει make στο Nearest-Neighbors/
  • αντιγράφει το Nearest-Neighbors/search σε black_box/search
  • κάνει make και στο Neural-LSH/IVFFlat_build_knn (χρήσιμο για Neural-LSH pipeline)

Σημείωση: τα scripts απαιτούν έξτρα βιβλιοθήκες:

pip install pandas matplotlib

6. Step Α: Generate Embeddings (dataset FASTA → vectors file)

6.1 Τι κάνει

Διαβάζει dataset FASTA και παράγει embeddings με ESM-2, αποθηκεύοντάς τα σε SIFT/fvecs αρχείο (ανά διάνυσμα γράφει πρώτα int32 d και μετά d float32).

6.2 Εκτέλεση

Από <project-root>:

python Generating_Embeddings/protein_embed.py -i data/swissprot_50k.fasta -o embed_data/dataset.dat

Υποχρεωτικά ορίσματα

  • -i / --input_file : dataset FASTA (π.χ. data/swissprot_50k.fasta)
  • -o / --output_file: output vectors file (π.χ. embed_data/dataset.dat)

Αρχεία που παράγονται

  • embed_data/dataset.dat (ή ό,τι ορίστηκε στο -o) SIFT/fvecs embeddings, διαστάσεων N x D.
  • embed_data/dataset_ids.txt Ένα ID ανά γραμμή. Η γραμμή i αντιστοιχεί στο i-οστό διάνυσμα του dataset file.

7. Step Β: Search Benchmark (ANN vs BLAST)

7.1 Τι κάνει

Για κάθε query πρωτεΐνη:

  1. Κάνει embed τις query ακολουθίες σε προσωρινό fvecs (δεν χρειάζεται να τις κάνεις pre-embed χειροκίνητα).

  2. Τρέχει μία ή περισσότερες ANN μεθόδους:

    • lsh, hypercube, ivfflat, ivfpq μέσω black_box/search
    • neural μέσω Neural-LSH scripts (κάνει build index αν δεν υπάρχει)
    • (προαιρετικά) bruteforce baseline (ενεργοποιείται αυτόματα όταν ζητήσεις -method all)
  3. Τρέχει BLAST reference σε ίδιο dataset FASTA (φτιάχνει DB στην πρώτη εκτέλεση).

  4. Παράγει report με:

    • QPS / time per query
    • Recall@N vs BLAST Top-N
    • αναλυτικούς Top-print_n γείτονες με L2 distance, BLAST identity, “In BLAST Top-N?”, και bio comment (αν δεν έχεις --no_bio).

7.2 Εκτέλεση (example: όλα, N=50, print=10)

Από <project-root>:

python3 Search_Benchmark/protein_search.py \
  -d embed_data/dataset.dat \
  -q data/targets.fasta \
  -o out/results.txt \
  -method all \
  --recall_n 50 \
  --print_n 10 \
  --ids_file embed_data/ids.txt \
  --dataset data/swissprot_50k.fasta \
  --annot_tsv bio_data/annot.tsv \
  --pfam_tsv bio_data/pfam.filtered.tsv

Υποχρεωτικά ορίσματα

  • -d / --dataset_file : embedded dataset vectors file (π.χ. embed_data/dataset.dat)
  • -q / --query_file : query FASTA (π.χ. data/targets.fasta)
  • -o / --output_file : report file (π.χ. out/results.txt)
  • -method / --method : all|lsh|hypercube|ivfflat|ivfpq|neural

Κύρια προαιρετικά ορίσματα

  • --recall_n : N για Recall@N vs BLAST Top-N (default 50)
  • --print_n : πόσους γείτονες να εκτυπώσει αναλυτικά (default 10)
  • --ids_file : mapping file για dataset IDs
  • --dataset : dataset FASTA για BLAST (default data/swissprot_50k.fasta)
  • --annot_tsv, --pfam_tsv : TSV paths για bio comments
  • --no_bio : απενεργοποιεί bio comments

Hyperparameters ανά μέθοδο (CLI)

Μπορείς να τα ορίσεις από command line μέσω search_args.py:

Euclidean LSH

  • --lsh_k (default 6)
  • --lsh_L (default 8)
  • --lsh_w (default 2000.0)

Hypercube

  • --cube_kproj (default 12)
  • --cube_w (default 1.5)
  • --cube_M (default 5000)
  • --cube_probes (default 2)

IVF (shared for ivfflat/ivfpq)

  • --ivf_kclusters (default 1000)
  • --ivf_nprobe (default 50)

IVF-PQ

  • --ivfpq_M (default 16)
  • --ivfpq_nbits (default 8)

Neural LSH

  • --neural_T (default 10) (search-time)
  • --neural_m (default 256)
  • --neural_layers (default 2)
  • --neural_nodes (default 128)
  • --neural_knn_mode (approx ή brute, default approx)
  • --neural_kahip_mode (default 1)
  • --neural_index (default nlsh_model) → directory name μέσα στο black_box/

Outputs / Αρχεία που δημιουργούνται στο search

  • Report: το αρχείο που ήταν στο -o (π.χ. out/results.txt)

  • blast_out/:

    • BLAST DB prefix files (π.χ. swissprot_db.*)
  • black_box/:

    • Neural indices (π.χ. black_box/nlsh_model/) όταν τρέχει για -method neural ή all

8. Μαζικά Πειράματα / Grid Search (run_bench_grid.py)

Το run_bench_grid.py τρέχει πολλά runs του protein_search.py αλλάζοντας παραμέτρους ανά μέθοδο.

Παράδειγμα (τρέξε όλες τις μεθόδους με Recall@50 και print 10):

python3 run_bench_grid.py \
  -d embed_data/dataset.dat \
  -q data/targets.fasta \
  --recall_n 50 \
  --print_n 10 \
  --ids_file embed_data/ids.txt \
  --dataset data/swissprot_50k.fasta \
  --annot_tsv bio_data/annot.tsv \
  --pfam_tsv bio_data/pfam.filtered.tsv \
  --results_dir test_results \
  --summary_dir test_summary

Σημειώσεις:

  • Ο runner γράφει ένα report ανά run (στο results_dir) και ένα summary (stdout/stderr/params) ανά run (στο summary_dir).
  • Για Neural LSH φτιάχνει unique --neural_index name ανά set υπερπαραμέτρων ώστε να μην “πατάει” indices.

9. Προετοιμασία TSVs (bio_data scripts)

9.1 Φιλτράρισμα TSV (για να μην φορτώνει τεράστια αρχεία)

python bio_data/filter_tsv.py \
  --pfam <uniprot_pfam.tsv.gz> \
  --annot <uniprot_annot.tsv.gz> \
  --ids embed_data/ids.txt data/targets.fasta \
  --out_dir bio_data/filtered_uniprot \
  --pfam_out pfam.filtered.tsv \
  --annot_out annot.filtered.tsv \
  --acc_col Entry

9.2 Merge GO + InterPro σε annot TSV

Αν υπάρχει ξεχωριστό TSV με GO/InterPro και θέλουμε να τα ενσωματώσουμε στο annot:

python3 bio_data/THE_MERGER.py annot.tsv dataset.interpro_go.tsv annot_with_go_ipr.tsv

10. Troubleshooting / Σημαντικές Παρατηρήσεις

  1. Πρώτη εκτέλεση BLAST είναι αργή Γιατί γίνεται makeblastdb και γράφονται αρχεία στο blast_out/. Οι επόμενες εκτελέσεις είναι ταχύτερες.

  2. Bio comments εμφανίζονται μόνο σε “Twilight Zone” περιπτώσεις Το bio_comment.py επιστρέφει σχόλιο κυρίως όταν το BLAST identity είναι < 30% ή δεν υπάρχει BLAST hit, και υπάρχουν ενδείξεις (κοινά Pfam/GO/EC/InterPro).


11. Γρήγορο “Happy Path” (ενδεικτικά βήματα)

# 1) env + deps + BLAST
python -m venv .venv
source .venv/bin/activate
pip install numpy scikit-learn fair-esm kahip
# (torch ανάλογα με CPU/CUDA)
sudo apt install -y ncbi-blast+

# 2) build binaries
bash search_preparation.sh

# 3) embeddings
python Generating_Embeddings/protein_embed.py -i data/swissprot_50k.fasta -o embed_data/dataset.dat

# 4) benchmark
python Search_Benchmark/protein_search.py \
  -d embed_data/dataset.dat \
  -q data/targets.fasta \
  -o results.txt \
  -method all \
  --recall_n 50 \
  --print_n 10 \
  --ids_file embed_data/ids.txt \
  --dataset data/swissprot_50k.fasta \
  --annot_tsv bio_data/annot.tsv \
  --pfam_tsv bio_data/pfam.filtered.tsv

About

A hybrid C++/Python pipeline for remote protein homology detection, coupling ESM-2 language model embeddings with custom Neural-LSH for scalable approximate nearest neighbor search.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages