Domanda:
Come aggiornare il codice e i dati durante l'analisi?
Iakov Davydov
2017-05-18 14:27:51 UTC
view on stackexchange narkive permalink

Attualmente sto cercando un sistema che mi permetta di versione sia il codice che i dati nella mia ricerca.

Penso che il mio modo di analizzare i dati non sia raro e questo sarà utile per molte persone fanno bioinformatica e mirano alla riproducibilità.

Ecco i requisiti:

  • L'analisi viene eseguita su più macchine (locale, cluster, server).
  • Tutto il codice è sincronizzato in modo trasparente tra le macchine.
  • Controllo delle versioni del codice sorgente.
  • Controllo delle versioni dei dati generati.
  • Supporto per un numero elevato di piccoli file generati (> 10k). Anche questi potrebbero essere eliminati.
  • Supporto per file di grandi dimensioni (> 1 Gb). Ad un certo punto i vecchi file generati possono essere eliminati definitivamente. Sarebbe folle avere una sincronizzazione trasparente di questi, ma essere in grado di sincronizzarli su richiesta sarebbe bello.

Finora sto usando git + rsync / scp. Ma ci sono diversi aspetti negativi.

  • La sincronizzazione tra più macchine è un po 'noiosa, cioè devi git pull prima di iniziare a lavorare e git push dopo ogni aggiornamento. Posso conviverci.
  • Non dovresti memorizzare file di dati generati di grandi dimensioni o un numero elevato di file all'interno del tuo repository.
  • Quindi devo sincronizzare i file di dati manualmente usando rsync, che è soggetto a errori.

C'è qualcosa chiamato git annex. Sembra davvero vicino a ciò di cui ho bisogno. Ma:

  • Un po 'più di lavoro di git, ma va bene.
  • Purtroppo sembra che non funzioni bene con il gran numero di file. Spesso nella mia analisi ho più di 10k piccoli file. Esistono alcuni trucchi per migliorare l'indicizzazione, ma non risolve il problema. Quello di cui ho bisogno è un collegamento simbolico che rappresenti l'intero contenuto della directory.

Una potenziale soluzione è utilizzare Dropbox o qualcosa di simile (come sincronizzazione) in combinazione con git. Ma lo svantaggio è che non ci sarà alcuna connessione tra la versione del codice sorgente e la versione dei dati.

Esiste un sistema di controllo delle versioni per il codice e i dati che soddisfano i requisiti che puoi consigliare?

Non è esattamente quello che stai cercando, né è in una posizione in cui lo userei a tempo pieno, ma ho scritto un pezzo di software chiamato `chitin`: https://github.com/SamStudio8/chitin /. È progettato per tenere traccia di come sono stati creati i file e cosa è successo loro. Non è progettato per memorizzare le modifiche (come git), ma in realtà trovo i metadati molto più utili delle modifiche effettive (a parte il codice, che ovviamente risiede in git).
@SamStudio8 sembra interessante. Non sono ancora del tutto convinto, ma IMHO vale la pena postare come risposta.
L'approccio normale per questo è avere una singola directory che viene esportata sulle varie macchine (locale, cluster, server). Perché duplicheresti i dati in questo modo invece di utilizzare solo un repository centralizzato?
@terdon spesso non hai un accesso root su un cluster, quindi non puoi semplicemente montare un filesystem di rete lì (e se ci sono molti file piccoli o file grandi che non vuoi a causa delle prestazioni). In un altro senso, questo è simile a una soluzione di sincronizzazione / dropbox, che non dispone del corretto controllo delle versioni e della corrispondenza tra il codice sorgente e i dati.
Bene, se hai bisogno di sincronizzare GB di dati, stai sbagliando. Se hai bisogno di un accesso root, chiederei al tuo amministratore di sistema di configurare il sistema in un modo che ti consenta di avere unità condivise. Non ho mai visto nessuno lavorare nel modo in cui descrivi, tutti e tre i posti in cui ho lavorato hanno sempre avuto unità di rete condivise. In alternativa, potresti usare `sshfs` per montarli da solo senza bisogno dell'accesso root. Il carico di I / O di rete è davvero un fattore, tuttavia, a volte copiamo i dati su un'unità locale e li cancella dopo l'analisi.
@terdon più piccoli file è anche un problema per la maggior parte dei filesystem di rete. Sono d'accordo che sincronizzare gigabyte di dati non è sempre una buona idea, ma a volte un male inevitabile (nota, git annex non lo fa automaticamente; e va bene). Vedo molti gruppi bioinformatici nella mia università che hanno problemi molto simili, quindi almeno non è raro. `sshfs` è un'opzione, ma è di nuovo un filesystem di rete. E su molti cluster fuse non è disponibile nel kernel (incluso il nostro, che è uno dei più grandi cluster di solo bioinformatica di cui io sia a conoscenza).
Sono d'accordo con @terdon,, non c'è motivo per cui dovresti sincronizzare numerosi file di grandi dimensioni su più nodi. Se non si dispone dell'accesso root per montare un'unità di archiviazione di rete, è necessario ottenerla. Tutta la sincronizzazione dei file intaserà la rete e i tuoi amministratori dovrebbero volerlo evitare. Conservare più copie di file è una ricetta per il disastro, dovresti evitarlo a tutti i costi.
@woemler sembra che non fossi abbastanza chiaro. Non voglio la sincronizzazione trasparente dei gig di dati. Voglio solo che sia aggiornato e recuperabile. Ho aggiornato la domanda per renderla più chiara. Inoltre, mantenere 100k piccoli file su network fs è anche una ricetta per il disastro. Comunque, il problema dei file di grandi dimensioni è facilmente risolvibile con git annex; file piccoli è più complicato.
Sette risposte:
#1
+14
Michael Schubert
2017-05-18 21:57:58 UTC
view on stackexchange narkive permalink

Ci sono un paio di punti da considerare qui, che descrivo di seguito. L'obiettivo qui dovrebbe essere quello di trovare un flusso di lavoro che sia minimamente invadente oltre a utilizzare già git.

Al momento, non esiste un flusso di lavoro ideale che copra tutti i casi d'uso, ma quello che descrivo di seguito è quanto di più vicino potrei arrivarci.

La riproducibilità non è solo conservare tutti i tuoi dati

Hai i tuoi dati grezzi con cui inizi il tuo progetto.

Tutti gli altri dati nella directory del progetto non dovrebbero mai "essere lì", ma avere una registrazione della loro provenienza. Gli script di elaborazione dei dati sono ottimi per questo, perché documentano già come sei passato dai dati grezzi a quelli analitici, e poi i file necessari per le tue analisi.

E quegli script possono essere dotato di versione, con un punto di ingresso appropriato per l'elaborazione (ad esempio un Makefile che descrive come eseguire i tuoi script).

In questo modo, viene definito lo stato di tutti i tuoi file di progetto dai dati grezzi e dalla versione degli script di elaborazione (e delle versioni del software esterno, ma questo è un tipo di problema completamente diverso).

Quali dati / codice dovrebbero e non dovrebbero essere dotati di versione

Proprio come non faresti per i file di codice generati dalla versione, non dovresti desiderare i file di dati intermedi della versione 10k che hai prodotto durante l'esecuzione delle analisi. I dati di cui dovrebbero essere versioni sono i tuoi dati grezzi (all'inizio della pipeline), non i file generati automaticamente.

Potresti voler prendere istantanee della directory del progetto, ma non conservare tutte le versioni di ogni file mai prodotte. Questo già riduce il problema con un discreto margine.

Approccio 1: controllo delle versioni effettivo dei dati

Per i tuoi dati grezzi o analitici , Git LFS (e in alternativa Git Annex, che hai già menzionato) è progettato per risolvere esattamente questo problema: aggiungi le informazioni di tracciamento dei file nel tuo albero Git, ma non memorizzare il contenuto di quei file nel repository (perché altrimenti aggiungerebbe la dimensione di un file non diffondibile ad ogni modifica che fai).

Per i tuoi file intermedi , fai la stessa cosa che faresti con i file di codice intermedi: aggiungili al tuo .gitignore e non eseguirne la versione.

Ciò richiede un paio di considerazioni:

  • Git LFS è un servizio a pagamento di Github (il livello gratuito è limitato a 1 GB di spazio di archiviazione / larghezza di banda al mese, che è molto poco), ed è più costoso di altre soluzioni di cloud storage comparabili. Potresti considerare di pagare per l'archiviazione su Github o di eseguire il tuo server LFS (c'è un'implementazione di riferimento, ma presumo che questo sarebbe comunque uno sforzo sostanziale)
  • Git Annex è gratuito, ma sostituisce i file con link e quindi modifica timestamp, che è un problema per es Flussi di lavoro basati su GNU Make (il principale svantaggio per me). Inoltre, il recupero dei file deve essere eseguito manualmente o tramite un commit hook

Approccio 2: solo codice di controllo delle versioni, sincronizzazione dei dati

Se i dati analitici rimangono gli stessi per la maggior parte delle tue analisi, quindi l'effettiva necessità di renderne la versione (al contrario di eseguire il backup e documentare la provenienza dei dati, che è essenziale) potrebbe essere limitata.

La chiave per ottenere questo funzionamento è mettere tutto file di dati nel tuo .gitignore e ignora tutti i tuoi file di codice in rsync , con uno script nella radice del tuo progetto ( estensioni e directory sono solo un esempio):

  #! / bin / bashcd $ (dirname $ 0) rsync -auvr \ --exclude "* .r" \ --include "* .RData "\ --exclude" dir con file enormi che non ti servono localmente "\ yourhost: / your / project / path / *.  

Il vantaggio qui è che non è necessario ricordare il comando rsync che stai eseguendo. Lo script stesso passa al controllo della versione.

Ciò è particolarmente utile se si eseguono elaborazioni pesanti su un cluster di elaborazione ma si desidera creare grafici dai file dei risultati sulla macchina locale. Ritengo che generalmente non sia necessaria la sincronizzazione bidirezionale.

A proposito, puoi usare l'hash dei file invece del timestamp almeno in biomake (doi: 10.1093 / bioinformatics / btx306).
@IakovDavydov Ne sono a conoscenza, ma in realtà non ho provato se funziona
+1 per tutte le modifiche sui dati grezzi dovrebbe essere documentato +1 per l'hash del file. Io stesso sono un grande fan della programmazione alfabetizzata e ho anche approfittato di questo approccio per documentare la versione dei miei strumenti / pacchetti che ho usato per l'analisi e l'hash dei dati grezzi. Quindi, quando vedo un risultato o una trama ho anche il suo contesto di produzione.
#2
+9
Sam Nicholls
2017-05-18 14:51:52 UTC
view on stackexchange narkive permalink

La tua domanda è in qualche modo aperta, ma penso che potrebbe rivelarsi una discussione interessante. Non credo che in molti casi valga la pena memorizzare i dati che hai creato in git . Come hai notato, non è progettato per file di grandi dimensioni (sebbene abbiamo git-lfs ) e sicuramente non è progettato per formati binari come BAM .

Sono dell'opinione che come è stato creato un file e cosa è stato fatto da allora è la chiave. I file di grandi dimensioni che hanno richiesto molti sforzi per essere creati dovrebbero essere specchiati da qualche parte (ma non necessariamente in un sistema di controllo della versione). Altri file meno importanti (o meno difficili da creare) che sono stati persi, danneggiati o altrimenti contaminati possono essere rigenerati purché tu sappia come sono diventati.

Per quello che vale, ho ha lavorato su un pezzo di software chiamato chitin (auto descritto come un guscio per bioinformatici disorganizzati). Ho anche scritto un lungo post sul blog sul motivo per cui pensavo che questo fosse un progetto necessario per me, ma il motivo principale era che nonostante i miei tentativi di organizzare il mio filesystem e fare buoni archivi dei miei esperimenti, nel tempo ho dimentica il significato dei miei nomi di directory abbreviati, o esattamente quale programma ha generato i dati.

L'obiettivo di chitin è quello di catturare automaticamente le modifiche apportate al file system durante l'esecuzione di un comando . Sa quali comandi eseguire per ricreare un particolare file, quali comandi hanno utilizzato quel file e può dirti quando e perché quel file è stato modificato (e anche da chi;).

Non è finito (niente lo è mai), ma sento che potresti andare sulla strada sbagliata volendo memorizzare tutti i tuoi dati e le sue versioni quando in realtà, penso che la maggior parte delle persone voglia solo conoscere i comandi che hanno istigato i cambiamenti. Se la cronologia dei dati è importante (e il tuo codice è ben aggiornato), puoi semplicemente controllare qualsiasi commit ed eseguire la tua analisi per rigenerare i dati.

Mi dispiace ma sto votando per difetto. Punto di discussione interessante, ma senza risposta alla domanda del PO.
#3
+6
Daniel Standage
2017-05-21 12:27:58 UTC
view on stackexchange narkive permalink

Prima di tutto, complimenti a te per aver preso sul serio il controllo delle versioni. Il fatto che tu sia consapevole di questo problema è un buon segno che vuoi fare una ricerca responsabile!

Per molti progetti di bioinformatica, i file di dati sono così grandi che il controllo delle versioni dei dati direttamente con uno strumento come git è poco pratico. Ma la tua domanda riguarda davvero un paio di questioni diverse.

  • Come faccio a svolgere la mia ricerca in modo riproducibile e mostro la provenienza completa di ogni punto dati e risultato che produco?
  • Come faccio a gestire e sincronizzare il mio lavoro di ricerca su più macchine?

La risposta breve :

  • Archivia i dati principali.
  • Metti il ​​tuo flusso di lavoro sotto il controllo della versione.
  • Checksum della versione di file di dati di grandi dimensioni.
  • Utilizza GitHub per sincronizzare il flusso di lavoro tra le macchine.

La risposta lunga :

Archivia i dati primari

Per quanto riguarda la riproducibilità, ciò che conta di più sono i dati primari: i dati grezzi e non elaborati raccolti dallo strumento. Se stai analizzando dati che sono stati pubblicati da altri, scrivi uno script che automatizzi l'attività di download dei dati dalla sua fonte ufficiale principale e metti quello script sotto il controllo della versione.

Se tu o un un compagno di laboratorio o un collega ha prodotto i dati e non sono ancora stati pubblicati, quindi dovresti già avere dei piani per inviarli a un archivio. In effetti, la maggior parte delle riviste e delle agenzie di finanziamento ora lo richiedono prima della pubblicazione. Mi spingerei addirittura a dire che i dati dovrebbero essere inviati non appena raccolti. Gli scienziati si preoccupano molto del furto dei loro dati e delle loro idee, ma statisticamente parlando, essere scoperti è molto meno probabile che nessuno tocchi i tuoi dati o legga il tuo articolo. Ma se tu o un consulente insistete, la maggior parte degli archivi di dati consente di mantenere i dati privati ​​per un periodo di tempo prolungato fino alla pubblicazione di un manoscritto di supporto.

Mettere (ad esempio) file Fastq in un repository git è una cattiva idea per molte ragioni. Nessun servizio di hosting supporterà file così grandi, git sarà molto lento con file così grandi, ma soprattutto git / GitHub non è un archivio! Usa un archivio dati appropriato!

Metti il ​​tuo flusso di lavoro sotto il controllo della versione

Tratta i tuoi dati grezzi come di sola lettura. Elaborare i dati grezzi solo utilizzando gli script e mantenere questi script sotto il controllo della versione. Vince Buffalo lo descrive bene nel suo libro Bioinformatics Data Skills. Dai un'occhiata!

Checksum della versione di file di dati di grandi dimensioni

Se ci sono file di dati che desideri monitorare ma sono troppo grandi per essere posti sotto il controllo della versione, calcola i checksum e posizionali questi sotto il controllo della versione. I checksum sono stringhe alfanumeriche molto piccole che sono, per tutti gli scopi pratici, univoche per ogni file di dati. Quindi, invece di mettere quel file Fastq tagliato da 5 GB o il file BAM da 7 GB sotto il controllo della versione, calcola i loro checksum e metti i checksum sotto il controllo della versione. I checksum non ti diranno il contenuto dei tuoi file, ma possono dirti quando il contenuto del file cambia.

Questo dovrebbe fornire piena divulgazione e completa provenienza per ogni punto dati nella tua analisi. Il flusso di lavoro ha uno script / comando per il download dei dati primari, script / comandi per l'elaborazione dei dati e checksum che fungono da firma per convalidare i file di output intermedi e finali. Con questo, chiunque dovrebbe essere in grado di riprodurre la tua analisi!

Usa GitHub per sincronizzare il tuo flusso di lavoro tra macchine

Se il tuo flusso di lavoro è già sotto il controllo della versione con git, è banale spingerlo a un servizio di hosting come GitHub, GitLab o BitBucket. Quindi è solo questione di utilizzare git push e git pull per mantenere il codice aggiornato sulle varie macchine.

#4
+5
H. Gourlé
2017-05-18 17:46:13 UTC
view on stackexchange narkive permalink

Open Science Framework utilizza il controllo delle versioni per tutti i file ed è gratuito: https://osf.io

Puoi integrare dati o codice da varie fonti come github, dropbox, google drive, figshare o amazon cloud

Puoi anche archiviare file sul loro server utilizzando l'archiviazione dati OSF, ma non so esattamente quale sia il limite di dimensione del file.

#5
+4
Ian Sudbery
2017-05-19 14:33:59 UTC
view on stackexchange narkive permalink

Il modo in cui gestiamo questo è:

  • Tutto il lavoro viene svolto in un singolo filesystem montato sul cluster
  • Questo file system è montato su macchine locali tramite sshfs / samba (a seconda della posizione della macchina "locale" corrente sulla rete).
  • Il codice è aggiornato con git hub
  • Tutti i calcoli vengono eseguiti tramite pipeline automatizzate leggere . Usiamo ruffus in combinazione con uno strato di utilità interno. Il sistema non ha molta importanza fintanto che non è più lavoro da aggiungere un altro passaggio alla pipeline di quanto sarebbe eseguirlo manualmente.
  • Tutte le decisioni di progettazione discutibili sono codificate in file di configurazione. Questi file di configurazione, insieme a un output di log molto dettagliato dalla pipeline (cosa è stato eseguito, qual è stato il commit git del codice eseguito, qual è stato il timestamp dei file su cui è stato eseguito, ecc.) Ei file di input iniziali sono versione controllata.
  • Il vantaggio di questo è che codice + configurazione + tempo = output. Non è previsto che l'intera pipeline venga rieseguita ogni volta che viene modificato qualcosa, ma la pipeline ti dirà se qualcosa non è aggiornato (può utilizzare timestamp o hash di file) e può essere eseguito tutto in una volta prima della pubblicazione.
  • Ogni altra analisi viene eseguita su quaderni juptyer. Questi sono controllati dalla versione.

Per riassumere, non eseguiamo la sincronizzazione perché lavoriamo sempre e solo da una posizione del disco anche se utilizziamo più posizioni della CPU. Controlliamo la versione:

  • Codice
  • Input, configurazione, log
  • Notebook Juptyer

Log registra il commit git usati per produrre gli output correnti.

Interessante Ian, questo è il tipo di design a cui aspiro, ma non lo metto davvero in pratica. Sono incuriosito da questo strato interno sopra il ruffus, che cos'è?
Il trucco sta nel rendere più semplice la scrittura di un'attività della pipeline rispetto a uno script di invio del lavoro del cluster. Il livello di utilità è fornito da CGATPipelines (www.github.com/CGATOxford/CGATPipelines)
#6
+3
woemler
2017-05-18 18:44:31 UTC
view on stackexchange narkive permalink

Usare Git per il controllo della versione del codice è una buona pratica, ma non si presta bene al controllo delle versioni di file di dati di grandi dimensioni. La sincronizzazione manuale dei dati su più nodi richiede problemi, desideri che questa sincronizzazione venga gestita automaticamente in un ambiente gestito o tieni semplicemente i file su un singolo dispositivo di archiviazione collegato alla rete.

Uno strumento che potresti da esaminare è Arvados, progettato per sincronizzare i dati e i flussi di lavoro bioinformatici su più macchine. Dal sito web del progetto:

Arvados è una piattaforma per l'archiviazione, l'organizzazione, l'elaborazione e la condivisione di dati genomici e altri big data. La piattaforma è progettata per rendere più facile per i data scientist sviluppare analisi, gli sviluppatori per creare applicazioni web genomiche e gli amministratori IT per gestire risorse genomiche di elaborazione e archiviazione su larga scala. La piattaforma è progettata per funzionare nel cloud o sul tuo hardware.

Userei Arvados solo se fosse davvero molto meglio di prima.
@nuin: Che cosa in particolare pensi che mancasse e / o lo renderebbe non appropriato come soluzione al problema dell'OP?
@woemier Non l'ho provato ultimamente e se non ricordo male era un PITA per impostare ed eseguire cose semplici. Ma come ho detto, non so se è migliorato.
#7
+3
weiji14
2018-03-27 08:17:13 UTC
view on stackexchange narkive permalink

Questa risposta coprirà solo le parti dei big data, cioè cose> 100 MB, e solo se la tua pipeline di analisi è collegata all'ecosistema Python. Richiederà un po 'di apprendimento

Prova a utilizzare quilt che è una specie di "finestra mobile per i dati" ( pagina Github).

  $ pip install quilt $ quilt install uciml / iris -x da2b6f5 #note the short hash $ python>>> from quilt.data.uciml import iris # you got data  

Pro:

  • Non sembra esserci un limite di dimensione del file per i pacchetti pubblici (non è stato testato sotto stress)
  • Hash dei dati per garantire la riproducibilità
  • Supporto per versioning e tag

Contro:

  • La memorizzazione di dati privati ​​parte da $ 7 per utente / mese fino a 1 TB di dati
  • Praticamente Python solo a questo punto, con un po 'di supporto della comunità per R

Maggiori informazioni qui.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...