Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision Next revision Both sides next revision | ||
user:zeman:joshua [2009/06/01 16:42] zeman vytvořeno |
user:zeman:joshua [2010/03/08 15:46] zeman Long sentences are problem. |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Joshua ====== | ====== Joshua ====== | ||
- | Toto jsou Danovy poznámky k práci s hierarchickým překladovým dekodérem Joshuou (reimplementace Hiera (David Chiang) v Javě od lidí z JHU). | + | Toto jsou Danovy poznámky k práci s hierarchickým překladovým dekodérem Joshuou (reimplementace Hiera (David Chiang) v Javě od lidí z JHU (Zhifei Li)). |
Zdroje informací: | Zdroje informací: | ||
* Soubory '' | * Soubory '' | ||
+ | * http:// | ||
+ | * http:// | ||
+ | * http:// | ||
+ | * http:// | ||
+ | * http:// | ||
===== Instalace ===== | ===== Instalace ===== | ||
- | Pozor, aby to běželo na clusteru LRC, je potřeba to překládat | + | Prerekvizity: |
+ | * Ant: kompilátor a make Javy. Máme ho v ''/ | ||
+ | * Swig: nástroj na propojení kódu napsaného v různých jazycích, v tomto případě Joshuy (Java) na SRILM (céčko). Máme ho v ''/ | ||
+ | * [[SRILM]]: nástroj Andrease Stolckeho na trénování a používání jazykových modelů, běžně používaný se strojovými překladači, jako je Pharaoh, Hiero, Moses, Joshua. Máme nainstalováno nejspíš mnohokrát, v podstatě si každý instaluje svou kopii. Podrobnosti o instalaci viz odkaz na začátku tohoto bodu. Pozor, aby instalace fungovala na stroji (architektuře), na kterém chceme | ||
+ | |||
+ | Nastavit důležité proměnné (to by se hodilo | ||
+ | |||
+ | < | ||
+ | setenv SRILM / | ||
+ | setenv JOSHUA / | ||
Stáhnout aktuální verzi Joshuy: | Stáhnout aktuální verzi Joshuy: | ||
- | < | + | < |
svn co https:// | svn co https:// | ||
- | Nastavit | + | Poznámka: Na začátku června 2009 jsem měl problémy se zdrojáky získanými přímo z SVN (třída SuffixArray neobsahovala metodu main()), ale možná to byl jen dočasný výpadek dokumentace, |
+ | |||
+ | http:// | ||
+ | |||
+ | přešel na link Download a stáhnul si aktuální release verzi. | ||
+ | |||
+ | Přeložit Joshuu: | ||
+ | |||
+ | < | ||
+ | ant compile</ | ||
+ | |||
+ | Kdyby bylo potřeba v budoucnosti překompilovat Joshuu načisto, již zkompilované moduly se dají odstranit pomocí | ||
+ | |||
+ | < | ||
+ | |||
+ | Otestujeme, že je Joshua funkční: | ||
+ | |||
+ | < | ||
+ | ./ | ||
+ | ./ | ||
+ | |||
+ | Joshuu jsem překládal na zenu. Teď je ještě potřeba otestovat, že funguje i na clusteru, třeba na počítači sol1. A ejhle, na 64 bitech přestala fungovat spolupráce se SRILM. | ||
+ | |||
+ | < | ||
+ | Jun 1, 2009 9:35:43 PM joshua.decoder.JoshuaConfiguration readConfigFile | ||
+ | INFO: you use a LM feature function, so make sure you have a LM grammar | ||
+ | Exception in thread " | ||
+ | at java.lang.ClassLoader$NativeLibrary.load(Native Method) | ||
+ | at java.lang.ClassLoader.loadLibrary0(ClassLoader.java: | ||
+ | at java.lang.ClassLoader.loadLibrary(ClassLoader.java: | ||
+ | at java.lang.Runtime.loadLibrary0(Runtime.java: | ||
+ | at java.lang.System.loadLibrary(System.java: | ||
+ | at joshua.corpus.vocab.SrilmSymbol.< | ||
+ | at joshua.decoder.JoshuaDecoder.initializeSymbolTable(JoshuaDecoder.java: | ||
+ | at joshua.decoder.JoshuaDecoder.initialize(JoshuaDecoder.java: | ||
+ | at joshua.decoder.JoshuaDecoder.< | ||
+ | at joshua.decoder.JoshuaDecoder.main(JoshuaDecoder.java: | ||
+ | |||
+ | Přestože SRILM, který nebyl přeložen na 64 bitech, běží jak na 32, tak na 64 bitech, s Joshuou na 64 bitech spolupracovat neumí (na 32 ano). Nepomůže ani když překlad Joshuy pustím až na 64 bitech (při spolupráci s 32bitovým SRILM). | ||
+ | |||
+ | **Nicméně se zdá, že pomohlo následující: | ||
+ | * Nalogoval jsem se na sol1 (aby kompilace probíhala na clusterové 64bitové architektuře). | ||
+ | * Upravil jsem $SRILM/ | ||
+ | * Vlezl jsem do $SRILM/ | ||
+ | * make clean, pak make World | ||
+ | * Vrátil jsem se do $JOSHUA_HOME a pustil ant clean, pak ant compile, nakonec ant test a hlavně ten ./ | ||
+ | |||
+ | ==== Cluster ==== | ||
+ | |||
+ | Ke spuštění Joshuy na clusteru se hodí např. Ondrova obálka (nebo i ta moje vlastní, ale tu bych neměl nutit např. Gauravovi, když jako jeden z mála pořád pracuju s tcsh). | ||
+ | |||
+ | < | ||
+ | ssh lrc-two | ||
+ | cd $JOSHUA | ||
+ | ~bojar/ | ||
+ | qstat -u '*'</ | ||
+ | |||
+ | |||
+ | ===== Extrakce gramatiky ===== | ||
+ | |||
+ | Joshua je nainstalován a funguje. Nyní se musíme naučit, jak ho trénovat a jak ho použít k překladu. | ||
+ | |||
+ | Nejdříve potřebujeme získat paralelní data, to je úkol mimo Joshuu. | ||
+ | * Tokenizovaný a segmentovaný text ve zdrojovém jazyce (en). | ||
+ | * Tokenizovaný a segmentovaný text v cílovém jazyce (hi). | ||
+ | * Párování vyrobíme [[Giza++|Gizou++]]. Správný soubor s párováním má stejný počet řádků jako zdrojový a cílový text (co řádek, to věta), ale místo slov má na každém řádku posloupnost dvojic čísel (např. "2-0 2-1 2-2 2-3 1-4"). Čísla vyjadřují, | ||
+ | |||
+ | A takhle pustíme Joshuu, aby z trénovacích dat extrahoval gramatiku. Joshua z nějakého | ||
+ | |||
+ | < | ||
+ | setenv SRC corpus/ | ||
+ | setenv TGT corpus/ | ||
+ | setenv ALI model/ | ||
+ | setenv TST corpus/ | ||
+ | setenv GRM en-hi.grammar | ||
+ | head -1 $SRC > $TST | ||
+ | java -cp $JOSHUA/bin joshua.prefix_tree.ExtractRules \ | ||
+ | --source=$SRC --target=$TGT --alignments=$ALI --test=$TST \ | ||
+ | --output=$GRM.unsorted --maxPhraseLength=5 | ||
+ | sort -u $GRM.unsorted > $GRM | ||
+ | gzip $GRM</ | ||
+ | |||
+ | V příkladu v INSTALL.txt měli navíc ještě volbu '' | ||
+ | |||
+ | Pozor, je poměrně snadné vyčerpat paměť. Tomu se dá čelit jednak tím, že se přesuneme na stroj, který má více paměti, jednak že zvolíme postup, který je složitější, | ||
+ | |||
+ | Binarizovat zdrojovou část korpusu. | ||
+ | |||
+ | < | ||
+ | $WORK/ | ||
+ | $WORK/ | ||
+ | $WORK/ | ||
+ | $WORK/ | ||
+ | java -cp $JOSHUA/bin joshua.corpus.suffix_array.SuffixArray \ | ||
+ | $WORK/ | ||
+ | $WORK/ | ||
+ | $WORK/ | ||
+ | $WORK/ | ||
+ | java -cp $JOSHUA/bin joshua.corpus.alignment.AlignmentGrids \ | ||
+ | $WORK/ | ||
+ | $WORK/ | ||
+ | |||
+ | Takto se extrahuje gramatika pro konkrétní testovací data s pomocí binarizovaného korpusu: | ||
+ | |||
+ | < | ||
+ | --binary-source=true --binary-target=true \ | ||
+ | --source=model/ | ||
+ | --source-vocab=model/ | ||
+ | --source-suffixes=model/ | ||
+ | --alignmentsType=MemoryMappedAlignmentGrids --alignments=model/ | ||
+ | --test=corpus/ | ||
+ | --output=model/ | ||
+ | --maxPhraseLength=5</ | ||
+ | |||
+ | ===== Decoding ===== | ||
+ | |||
+ | Jakmile máme gramatiku (tj. překladový model), můžeme dekódovat neboli překládat. Bývá sice zvykem ještě nejdříve vyladit váhy jednotlivých komponent pomocí MERTu, ale MERT sám už dekódování používá a teoreticky se můžeme spokojit s dekódováním pomocí odhadnutých, | ||
+ | |||
+ | Parametry dekódování se zadávají prostřednictvím | ||
+ | |||
+ | Cesta k souboru s jazykovým modelem. Zatím předpokládám, | ||
+ | |||
+ | < | ||
+ | |||
+ | Cesta k souboru s překladovým modelem, tedy s gramatikou vyextrahovanou pro daný testovací soubor. Formát má být stejný, jako produkuje Hiero. Předpokládám, | ||
+ | |||
+ | < | ||
+ | tm_format=hiero</ | ||
+ | |||
+ | Jakýsi spojovací soubor, glue_file. Vůbec nevím, co to je. Joshua ale jeden obsahuje a vypadá dost obecně, takže možná nezávisí na konkrétních trénovacích datech. | ||
+ | |||
+ | < | ||
+ | glue_format=hiero</ | ||
+ | |||
+ | Konfigurace jazykového modelu. Kopíruju ji z example2, akorát měním order na 3, protože jsem trénoval trigramy, nikoli čtyřgramy. | ||
+ | |||
+ | < | ||
+ | use_srilm=false | ||
+ | lm_ceiling_cost=100 | ||
+ | use_left_euqivalent_state=false | ||
+ | use_right_euqivalent_state=false | ||
+ | order=3</ | ||
+ | |||
+ | Konfigurace | ||
+ | |||
+ | < | ||
+ | span_limit=10 | ||
+ | phrase_owner=pt | ||
+ | mono_owner=mono | ||
+ | begin_mono_owner=begin_mono | ||
+ | default_non_terminal=X | ||
+ | |||
+ | #pruning config | ||
+ | fuzz1=0.1 | ||
+ | fuzz2=0.1 | ||
+ | max_n_items=30 | ||
+ | relative_threshold=10.0 | ||
+ | max_n_rules=50 | ||
+ | rule_relative_threshold=10.0</ | ||
+ | |||
+ | Konfigurace N-best listu (dekodér vrací N překladových hypotéz, které se mu jeví jako nejlepší, seřazených podle skóre, které jim přiřadil). Pro MERT potřebujeme N nejlepších hypotéz, abychom mohli každou z nich porovnat s referenčními překlady, spočítat BLEU skóre a případně upravit váhy, pokud má nejlepší BLEU skóre hypotéza, která se celkovým skóre nedostala na začátek seznamu, ale při jiném vyvážení komponent by se tam mohla dostat. Pro závěrečný překlad testovacích dat obvykle N nejlepších hypotéz nepotřebujeme, | ||
+ | |||
+ | < | ||
+ | use_unique_nbest=true | ||
+ | use_tree_nbest=false | ||
+ | add_combined_cost=true | ||
+ | top_n=300</ | ||
+ | |||
+ | Další sekce se týkají vzdáleného serveru | ||
+ | |||
+ | Následují váhy jednotlivých komponent (" | ||
+ | |||
+ | < | ||
+ | #lm order weight | ||
+ | lm 1.000000 | ||
+ | |||
+ | # | ||
+ | phrasemodel pt 0 1.066893 | ||
+ | phrasemodel pt 1 0.752247 | ||
+ | phrasemodel pt 2 0.589793 | ||
+ | |||
+ | # | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # | ||
+ | |||
+ | # | ||
+ | wordpenalty -2.844814</ | ||
+ | |||
+ | No a nakonec příkaz, kterým pustíme Joshuu s naším konfiguračním souborem (na clusteru): | ||
+ | |||
+ | < | ||
+ | "java -Xmx1200m -Xms1200m -cp $JOSHUA/bin joshua.decoder.JoshuaDecoder \ | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | I když si v konfiguračním souboru řekneme, že chceme N-best výstup pro N=1, dostaneme ho ve formátu, který | ||
+ | |||
+ | < | ||
+ | |||
+ | ===== Vyhodnocení úspěšnosti ===== | ||
+ | |||
+ | 1-best výstup Joshuy a referenční překlad bychom mohli převést do příslušného XML formátu a pustit na ně oficiální externí perlový skript, který počítá BLEU skóre. Pro výsledná čísla do článku bychom to tak také měli udělat. | ||
+ | |||
+ | Jinak ale Joshua obsahuje svůj vlastní kód pro vyhodnocování. Přehled parametrů jeho volání se dozvíme, když ho zavoláme bez argumentů: | ||
+ | |||
+ | < | ||
+ | |||
+ | S využitím | ||
+ | |||
+ | < | ||
+ | -cand $HINDI/ | ||
+ | -ref $HINDI/ | ||
+ | |||
+ | Bez MERTu mi zatím vyšlo BLEU = 0.0807. | ||
+ | |||
+ | ===== MERT ===== | ||
+ | |||
+ | Celý proces by nebyl úplný bez MERTu, což je zkratka za Minimum Error Rate Training. V principu | ||
+ | |||
+ | Většina parametrů se Z-MERTu předává prostřednictvím konfiguračního souboru. Přehled volání Z-MERTu se dozvíme takto: | ||
+ | |||
+ | < | ||
+ | |||
+ | Příklad použití Z-MERTu najdeme ve složce '' | ||
+ | |||
+ | Dále potřebujeme soubor (vlastně skript: měl by být spustitelný), | ||
+ | |||
+ | < | ||
+ | cp ../ | ||
+ | cp ../ | ||
+ | cp $JOSHUA/ | ||
+ | vi decoder-config</ | ||
+ | |||
+ | Změněné parametry: | ||
+ | |||
+ | < | ||
+ | tm_file=/ | ||
+ | glue_file=/ | ||
+ | order=3</ | ||
+ | |||
+ | < | ||
+ | chmod 755 decoder_command | ||
+ | vi decoder_command</ | ||
+ | |||
+ | Ve volání dekodéru musíme změnit cesty ke konfiguračnímu, | ||
+ | |||
+ | < | ||
+ | $HINDI/ | ||
+ | $HINDI/ | ||
+ | $HINDI/ | ||
+ | |||
+ | V konfiguraci Z-MERTu zohledníme právě upravené volání a konfiguraci dekodéru. | ||
+ | |||
+ | < | ||
+ | cp $JOSHUA/ | ||
+ | vi zmert-config.txt</ | ||
+ | |||
+ | Změněné parametry: | ||
+ | |||
+ | < | ||
+ | -s src.txt # source sentences file name | ||
+ | -r ref.txt # target sentences file name | ||
+ | -rps 1 # references per sentence | ||
+ | -maxIt 5 # maximum MERT iterations | ||
+ | -cmd ./ | ||
+ | -decOut nbest.txt # file produced by decoder | ||
+ | -dcfg decoder-config.txt # decoder config file</ | ||
+ | |||
+ | No a teď už můžeme spustit Z-MERT (případně to celé dát do uvozovek a před to '' | ||
+ | |||
+ | < | ||
+ | $HINDI/ | ||
+ | > $HINDI/ | ||
+ | |||
+ | ===== Troubleshooter ===== | ||
+ | |||
+ | |||
+ | ==== Grammar extraction: Negative array size ==== | ||
+ | |||
+ | If you encounter this exception during corpus binarization or (in older releases of Joshua) during grammar extraction, check your alignment file whether it matches your source and target corpus. Did you switch translation direction accidentially? | ||
+ | |||
+ | Another source of this error could be sentences with 100 or more words. This is not a strict limit, often I was able to extract grammars for corpora unchecked for such sentences, but according to Lance Schwartz, long sentences can cause problems. And after all, they are suspicious anyway, and their contribution to the learnt model is doubtful. | ||
+ | |||
+ | ==== ZMERT: corrupted temp file ==== | ||
+ | |||
+ | Hi all, | ||
+ | |||
+ | does the following ZMERT exception look familiar to anyone? My only idea was that the nbest output from the decoder is corrupted somehow. However, I cannot find anything strange in it, such as sequence of more then three " | ||
+ | |||
+ | Thanks, | ||
+ | Dan | ||
+ | |||
+ | zmert.out: | ||
+ | ----- | ||
+ | < | ||
+ | Processed the following args array: | ||
+ | -dir / | ||
+ | |||
+ | ---------------------------------------------------- | ||
+ | Initializing... | ||
+ | ---------------------------------------------------- | ||
+ | |||
+ | Random number generator initialized using seed: 12341234 | ||
+ | |||
+ | Number of sentences: 2051 | ||
+ | Number of documents: 1 | ||
+ | Optimizing BLEU | ||
+ | docSubsetInfo: | ||
+ | Number of features: 5 | ||
+ | Feature names: {" | ||
+ | |||
+ | c Default value Optimizable? | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | 4 | ||
+ | 5 | ||
+ | |||
+ | Weight vector normalization method: weights will be scaled so that the " | ||
+ | |||
+ | ---------------------------------------------------- | ||
+ | |||
+ | ---------------------------------------------------- | ||
+ | Z-MERT run started @ Sat Mar 06 23:52:57 CET 2010 | ||
+ | ---------------------------------------------------- | ||
+ | |||
+ | Initial lambda[]: {1.0, 1.066893, 0.752247, 0.589793, -2.844814} | ||
+ | |||
+ | --- Starting Z-MERT iteration #1 @ Sat Mar 06 23:52:57 CET 2010 --- | ||
+ | Decoding using initial weight vector {1.0, 1.066893, 0.752247, 0.589793, -2.844814} | ||
+ | Running external decoder... | ||
+ | ...finished decoding @ Sun Mar 07 00:02:33 CET 2010 | ||
+ | Reading candidate translations from iterations 1-1 | ||
+ | (and computing BLEU sufficient statistics for previously unseen candidates) | ||
+ | | ||
+ | Exception in thread " | ||
+ | at java.lang.NumberFormatException.forInputString(NumberFormatException.java: | ||
+ | at java.lang.Integer.parseInt(Integer.java: | ||
+ | at java.lang.Integer.parseInt(Integer.java: | ||
+ | at joshua.zmert.MertCore.run_single_iteration(MertCore.java: | ||
+ | at joshua.zmert.MertCore.main(MertCore.java: | ||
+ | Z-MERT exiting prematurely (MertCore returned 1)...</ | ||
+ | ----- | ||
+ | |||
+ | Omar's response: | ||
+ | |||
+ | Hi Dan, | ||
+ | |||
+ | The " | ||
+ | if there are any *temp* (or *tmp*) files in the folder from earlier | ||
+ | runs, make sure you delete them first, then try launching Z-MERT | ||
+ | again. | ||
+ | not delete them because they can be used to restart Z-MERT from the | ||
+ | point where it crashed. | ||
+ | loss or an interrupted job, etc. In your case, I think what happened | ||
+ | is that a prior run crashed because of an external problem in the | ||
+ | setup itself, which you fixed and tried to restart Z-MERT. | ||
+ | reason, Z-MERT should not be using those temp files in the first | ||
+ | place, but when it sees them there, it assumes it can use them because | ||
+ | the user did not delete them. | ||
+ | |||
+ | Let me know if that's not the case. | ||
+ | |||
+ | O.Z. | ||
- | < | ||
- | which ant # / | ||
- | which swig # / | ||
- | # install SRILM</ |