<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Yasmin Moslem</title>
    <description>Notes on efficient NLP and speech, including pruning, routing and cascades, distillation, quantization, serving, and machine translation.</description>
    <link>https://blog.yasmin.ie/</link>
    <atom:link href="https://blog.yasmin.ie/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 24 Oct 2026 13:43:37 +0000</pubDate>
    <lastBuildDate>Sat, 24 Oct 2026 13:43:37 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Iterative Layer Pruning for Efficient Inference</title>
        <description>&lt;p&gt;Model pruning is a compression technique, that aims to remove redundant components without significantly compromising the model’s performance or accuracy. This process facilitates efficient deployment of complex models by making them smaller and faster.&lt;/p&gt;

&lt;p&gt;Pruning is a hardware-agnostic compression approach. Unlike some other compression approaches such as quantisation, models resulting from structured pruning can be deployed on any modern GPU with similar performance gains. Moreover, pruning can be part of a sophisticated compression pipeline that incorporates other techniques such as quantisation and efficient fine-tuning (e.g. LoRA, QLoRA), which can lead to higher compression and efficiency levels.&lt;/p&gt;

&lt;p&gt;In this article, we will cover some insights from our two papers about Iterative Layer Pruning at IWSLT 2025 [1] and WMT 2025 [2].&lt;/p&gt;

&lt;h2 id=&quot;iterative-layer-pruning&quot;&gt;Iterative Layer Pruning&lt;/h2&gt;

&lt;p&gt;The process of Iterative Layer Pruning involves incrementally identifying and removing layers with minimal contribution to translation or generation quality, one layer at a time. The pruning process is usually followed by fine-tuning the resulting models on relevant training data to restore the translation quality. Moreover, knowledge distillation data from the baseline (teacher) model can be used to help the pruned (student) model to reach the quality of the teacher model.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/pruning/pruning-digram.png&quot; alt=&quot;pruning-digram&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;layer-importance-evaluation&quot;&gt;Layer Importance Evaluation&lt;/h2&gt;

&lt;p&gt;We conduct layer importance evaluation by measuring translation performance without each layer. The process is as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Remove one layer of the model.&lt;/li&gt;
  &lt;li&gt;Evaluate the model (chrF++).&lt;/li&gt;
  &lt;li&gt;Repeat for the rest of the layers.&lt;/li&gt;
  &lt;li&gt;Prune the least important layer (best chrF++ without it).&lt;/li&gt;
  &lt;li&gt;Repeat #1 to #4 until reaching the pruning target.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;evaluation-results&quot;&gt;Evaluation Results&lt;/h2&gt;

&lt;p&gt;For translation from Czech to German (CES-DEU), pruning 8 layers and then fine-tuning the resulting model retains 98% of the translation quality (as measured by COMET), while achieving considerable speedup gains. Interestingly, for translation from English to Egyptian Arabic (ENG-ARZ), the model resulting from pruning up to 16 layers and then fine-tuning outperforms the Aya-Expanse-8B baseline for this language pair. Pruned models achieve up to ~2× speedup.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/pruning/pruning-results-wmt.png&quot; alt=&quot;pruning-results&quot; style=&quot;zoom:70%;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;knowledge-distillation&quot;&gt;Knowledge Distillation&lt;/h2&gt;

&lt;p&gt;Knowledge Distillation aims at transferring knowledge from a larger model (teacher) to a smaller one (student). In “sequence-level” knowledge distillation, the student model is trained to generate sequences that match the teacher’s sequence outputs. Fine-tuning the pruned models on a combination of authentic and synthetic data (from Aya-Expanse-32B) improved the Czech to German (CES-DEU) translation quality, with the 24-layer pruned model nearly matching the performance of the Aya-Expanse-8B
baseline.&lt;/p&gt;

&lt;div style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;../static/img/pruning/pruning-results-wmt-kd.png&quot; alt=&quot;pruning-results&quot; style=&quot;zoom:40%;&quot; /&gt;&lt;/div&gt;

&lt;h2 id=&quot;further-performance-gains&quot;&gt;Further performance gains&lt;/h2&gt;

&lt;p&gt;It is highly recommended to use an efficient inference engine such as vLLM, which outperforms inference with the Transformers framework. In both cases, pruned models demonstrate up to ~2× speedup.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/pruning/trasformers-vllm.png&quot; alt=&quot;vLLM&quot; style=&quot;zoom:70%;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Moreover, you can quantise the pruned models for further compression. For example, in our IWSLT 2025 paper, we applied QLoRA after pruning the models. However, notice that low-precision quantisation (e.g. 4-bit and 8-bit) requires special hardware (e.g. H100 or H200) to observe performance gains.&lt;/p&gt;

&lt;h2 id=&quot;questions-and-answers&quot;&gt;Questions and Answers&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Q. Why iterative layer pruning instead of random or middle layer pruning?
    &lt;ul&gt;
      &lt;li&gt;A. Iterative layer pruning relies on layer importance analysis. Hence, only the layers with minimal contribution to the output quality can be removed. In our experiments, iterative layer pruning achieves better results than middle layer pruning.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Q. Can we prune other parts of the model other than layers?
    &lt;ul&gt;
      &lt;li&gt;A. There are two types of pruning, structured pruning and unstructured pruning. In structured pruning, you can remove whole layers, attention heads, or other entire computational blocks, while in unstructured pruning, you can remove individual weights from a neural network. While unstructured pruning can achieve higher compression rates, it requires specialised hardware for efficient deployment. On the contrary, models resulting from structure pruning can be deployed on standards GPUs.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Q. Is it better to fine-tune the baseline model &lt;em&gt;before&lt;/em&gt; pruning?
    &lt;ul&gt;
      &lt;li&gt;A. If your task, domain, or language is very different from the distribution of the baseline model, it is better to fine-tune the baseline model first. Otherwise, you can prune the baseline directly. On the contrary, fine-tuning &lt;em&gt;after&lt;/em&gt; pruning is always required to restore the quality of the baseline model.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Q. Can we fine-tune after each layer pruning step?
    &lt;ul&gt;
      &lt;li&gt;A. We experimented with both fine-tuning after each layer pruning step, and after a number of pruned layers. In both cases, there was no difference than just fine-tuning once after the end of the pruning process. This might be because of overfitting resulted from several fine-tuning passes.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Q. Can the same approach be applied to encoder-decoder models?
    &lt;ul&gt;
      &lt;li&gt;A. Yes, we applied this iterative layer pruning approach to both a decoder-only model, Aya-Expanse,  and an encoder-decoder model, Qwen2-Audio. However, for encoder-decoder models, we observed that only pruning the decoder leads to better overall performance.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;github-repository&quot;&gt;GitHub Repository&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/ymoslem/Model-Compression&quot;&gt;&lt;img src=&quot;https://github-readme-stats.vercel.app/api/pin/?theme=graywhite&amp;amp;username=ymoslem&amp;amp;repo=Model-Compression&quot; alt=&quot;Model-Compression&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://aclanthology.org/2025.iwslt-1.40/&quot;&gt;Efficient Speech Translation through Model Compression and Knowledge Distillation&lt;/a&gt; (Moslem, IWSLT 2025)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://aclanthology.org/2025.wmt-1.78/&quot;&gt;Iterative Layer Pruning for Efficient Translation Inference&lt;/a&gt; (Moslem et al., WMT 2025)&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Mon, 17 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/iterative-layer-pruning/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/iterative-layer-pruning/</guid>
        
        
        <category>efficiency</category>
        
        <category>llm</category>
        
        <category>mt</category>
        
        <category>speech</category>
        
      </item>
    
      <item>
        <title>Adaptive Translation and Terminology with Large Language Models</title>
        <description>&lt;p&gt;Large-scale language models (LLMs) have shown interesting capabilities of in-context learning, where they learn to replicate certain input-output text generation patterns, without further fine-tuning. By feeding an LLM at inference time with a prompt that consists of a list of translation pairs, it can then simulate the domain, terminology, and style characteristics.&lt;/p&gt;

&lt;h2 id=&quot;adaptive-machine-translation-with-large-language-models&quot;&gt;Adaptive Machine Translation with Large Language Models&lt;/h2&gt;

&lt;p&gt;First preprint: January 2023&lt;/p&gt;

&lt;p&gt;Peer-reviewed: EAMT 2023&lt;/p&gt;

&lt;h3 id=&quot;abstract&quot;&gt;Abstract:&lt;/h3&gt;

&lt;p&gt;Consistency is a key requirement of high-quality translation. It is especially important to adhere to pre-approved terminology and adapt to corrected translations in domain-specific projects. Machine translation (MT) has achieved significant progress in the area of domain adaptation. However, real-time adaptation remains challenging. Large-scale language models (LLMs) have recently shown interesting capabilities of in-context learning, where they learn to replicate certain input-output text generation patterns, without further fine-tuning. By feeding an LLM at inference time with a prompt that consists of a list of translation pairs, it can then simulate the domain and style characteristics. This work aims to investigate how we can utilize in-context learning to improve real-time adaptive MT. Our extensive experiments show promising results at translation time. For example, GPT-3.5 can adapt to a set of in-domain sentence pairs and/or terminology while translating a new sentence. We observe that the translation quality with few-shot in-context learning can surpass that of strong encoder-decoder MT systems, especially for high-resource languages. Moreover, we investigate whether we can combine MT from strong encoder-decoder models with fuzzy matches, which can further improve translation quality, especially for less supported languages. We conduct our experiments across five diverse language pairs, namely English-to-Arabic (EN-AR), English-to-Chinese (EN-ZH), English-to-French (EN-FR), English-to-Kinyarwanda (EN-RW), and English-to-Spanish (EN-ES).&lt;/p&gt;

&lt;div class=&quot;language-bib highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;@inproceedings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;moslem-etal-2023-adaptive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Adaptive Machine Translation with Large Language Models&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Moslem, Yasmin  and
      Haque, Rejwanul  and
      Kelleher, John D.  and
      Way, Andy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;booktitle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Proceedings of the 24th Annual Conference of the European Association for Machine Translation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;month&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;jun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2023&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Tampere, Finland&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;publisher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;European Association for Machine Translation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://aclanthology.org/2023.eamt-1.22/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;pages&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;227--237&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;domain-terminology-integration-into-machine-translation-leveraging-large-language-models&quot;&gt;Domain Terminology Integration into Machine Translation: Leveraging Large Language Models&lt;/h2&gt;

&lt;p&gt;First preprint: October 2023&lt;/p&gt;

&lt;p&gt;Peer-reviewed: WMT 2023&lt;/p&gt;

&lt;h3 id=&quot;abstract-1&quot;&gt;Abstract:&lt;/h3&gt;

&lt;p&gt;This paper discusses the methods that we used for our submissions to the WMT 2023 Terminology Shared Task for German-to-English (DE-EN), English-to-Czech (EN-CS), and Chinese-to-English (ZH-EN) language pairs. The task aims to advance machine translation (MT) by challenging participants to develop systems that accurately translate technical terms, ultimately enhancing communication and understanding in specialised domains. To this end, we conduct experiments that utilise large language models (LLMs) for two purposes: generating synthetic bilingual terminology-based data, and post-editing translations generated by an MT model through incorporating pre-approved terms. Our system employs a four-step process: (i) using an LLM to generate bilingual synthetic data based on the provided terminology, (ii) fine-tuning a generic encoder-decoder MT model, with a mix of the terminology-based synthetic data generated in the first step and a randomly sampled portion of the original generic training data, (iii) generating translations with the fine-tuned MT model, and (iv) finally, leveraging an LLM for terminology-constrained automatic post-editing of the translations that do not include the required terms. The results demonstrate the effectiveness of our proposed approach in improving the integration of pre-approved terms into translations. The number of terms incorporated into the translations of the blind dataset increases from an average of 36.67% with the generic model to an average of 72.88% by the end of the process. In other words, successful utilisation of terms nearly doubles across the three language pairs.&lt;/p&gt;

&lt;div class=&quot;language-bib highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;@inproceedings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;moslem-etal-2023-domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Domain Terminology Integration into Machine Translation: Leveraging Large Language Models&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Moslem, Yasmin  and
      Romani, Gianfranco  and
      Molaei, Mahdi  and
      Kelleher, John D.  and
      Haque, Rejwanul  and
      Way, Andy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;booktitle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Proceedings of the Eighth Conference on Machine Translation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;month&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2023&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Singapore&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;publisher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Association for Computational Linguistics&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://aclanthology.org/2023.wmt-1.82/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;doi&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;10.18653/v1/2023.wmt-1.82&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;pages&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;902--911&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;fine-tuning-large-language-models-for-adaptive-machine-translation&quot;&gt;Fine-tuning Large Language Models for Adaptive Machine Translation&lt;/h2&gt;

&lt;p&gt;First preprint: December 2023&lt;/p&gt;

&lt;p&gt;Published as: thesis chapter&lt;/p&gt;

&lt;h3 id=&quot;abstract-2&quot;&gt;Abstract:&lt;/h3&gt;

&lt;p&gt;This paper presents the outcomes of fine-tuning Mistral 7B, a general-purpose large language model (LLM), for adaptive machine translation (MT). The fine-tuning process involves utilising a combination of zero-shot and one-shot translation prompts within the medical domain. The primary objective is to enhance real-time adaptive MT capabilities of Mistral 7B, enabling it to adapt translations to the required domain at inference time. The results, particularly for Spanish-to-English MT, showcase the efficacy of the fine-tuned model, demonstrating quality improvements in both zero-shot and one-shot translation scenarios, surpassing Mistral 7B’s baseline performance. Notably, the fine-tuned Mistral outperforms ChatGPT “gpt-3.5-turbo” in zero-shot translation while achieving comparable one-shot translation quality. Moreover, the zero-shot translation of the fine-tuned Mistral matches NLLB 3.3B’s performance, and its one-shot translation quality surpasses that of NLLB 3.3B. These findings emphasise the significance of fine-tuning efficient LLMs like Mistral 7B to yield high-quality zero-shot translations comparable to task-oriented models like NLLB 3.3B. Additionally, the adaptive gains achieved in one-shot translation are comparable to those of commercial LLMs such as ChatGPT. Our experiments demonstrate that, with a relatively small dataset of 20,000 segments that incorporate a mix of zero-shot and one-shot prompts, fine-tuning significantly enhances Mistral’s in-context learning ability, especially for real-time adaptive MT.&lt;/p&gt;

&lt;div class=&quot;language-bib highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;@article&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;moslem-etal-2023-fine-tuning-llms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{Fine-tuning Large Language Models for Adaptive Machine Translation}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;na&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{Yasmin Moslem and Rejwanul Haque and Andy Way}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{2023}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;eprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{2312.12740}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;archivePrefix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{arXiv}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;primaryClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{cs.CL}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{https://arxiv.org/abs/2312.12740}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;github-repository&quot;&gt;GitHub Repository&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/ymoslem/Adaptive-MT-LLM-Fine-tuning&quot;&gt;&lt;img src=&quot;https://github-readme-stats.vercel.app/api/pin/?theme=graywhite&amp;amp;username=ymoslem&amp;amp;repo=Adaptive-MT-LLM-Fine-tuning&quot; alt=&quot;Adaptive-MT-LLM-Fine-tuning&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;language-modelling-approaches-to-adaptive-machine-translation&quot;&gt;Language Modelling Approaches to Adaptive Machine Translation&lt;/h2&gt;

&lt;p&gt;First preprint: January 2024&lt;/p&gt;

&lt;p&gt;Published as: PhD thesis (DCU)&lt;/p&gt;

&lt;h3 id=&quot;abstract-3&quot;&gt;Abstract:&lt;/h3&gt;

&lt;p&gt;Consistency is a key requirement of high-quality translation. It is especially important to adhere to pre-approved terminology and adapt to corrected translations in domain-specific projects. Machine translation (MT) has achieved significant progress in the area of domain adaptation. However, in-domain data scarcity is common in translation settings, due to the lack of specialised datasets and terminology, or inconsistency and inaccuracy of available in-domain translations. In such scenarios where there is insufficient in-domain data to fine-tune MT models, producing translations that are consistent with the relevant context is challenging. While real-time adaptation can make use of smaller amounts of in-domain data to improve the translation on the fly, it remains challenging due to supported context limitations and efficiency constraints. Large language models (LLMs) have recently shown interesting capabilities of in-context learning, where they learn to replicate certain input-output text generation patterns, without further fine-tuning. Such capabilities have opened new horizons for domain-specific data augmentation and real-time adaptive MT. This work attempts to address two main relevant questions: 1) in scenarios involving human interaction and continuous feedback, can we employ language models to improve the quality of adaptive MT at inference time? and 2) in the absence of sufficient in-domain data, can we use pre-trained large-scale language models to improve the process of MT domain adaptation?&lt;/p&gt;

&lt;div class=&quot;language-bib highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;@article&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;moslem-2024-adaptive-mt-llms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{Language Modelling Approaches to Adaptive Machine Translation, {PhD} thesis}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;na&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{Yasmin Moslem}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{2024}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;eprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{2401.14559}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;archivePrefix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{arXiv}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;primaryClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{cs.CL}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;{https://arxiv.org/abs/2401.14559}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://aclanthology.org/2023.eamt-1.22/&quot;&gt;Adaptive Machine Translation with Large Language Models&lt;/a&gt; (Moslem et al., EAMT 2023)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://aclanthology.org/2023.wmt-1.82/&quot;&gt;Domain Terminology Integration into Machine Translation: Leveraging Large Language Models&lt;/a&gt; (Moslem et al., WMT 2023)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2312.12740&quot;&gt;Fine-tuning Large Language Models for Adaptive Machine Translation&lt;/a&gt; (Moslem et al., thesis chapter 2023)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2401.14559&quot;&gt;Language Modelling Approaches to Adaptive Machine Translation&lt;/a&gt; (Moslem, PhD thesis, DCU 2024)&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 10 Jan 2024 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/adaptive-mt/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/adaptive-mt/</guid>
        
        
        <category>nmt</category>
        
        <category>llm</category>
        
      </item>
    
      <item>
        <title>Purely Synthetic Bilingual Data for Machine Translation?</title>
        <description>&lt;p&gt;In-domain data scarcity is common in translation settings, due to the lack of specialized datasets and terminology, or inconsistency and inaccuracy of available in-domain translations. You might be familiar to such situation when there is a big translation project, but there is only a tiny in-domain translation memory, or no translation memory at all. In the absence of sufficient domain-specific data required to fine-tune machine translation (MT) systems, adhering to the domain terminology and client’s style can be challenging.  Recently, there has been a considerable advancement in training large language models, not only for English, but also for diverse languages. Among autoregressive language models, trained to predict the next word in a sequence, are BLOOM, GPT-3, and GPT-J. The question is: &lt;strong&gt;can we use these large language models to generate more domain-specific &lt;em&gt;bilingual&lt;/em&gt; data?&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;method&quot;&gt;Method&lt;/h2&gt;

&lt;p&gt;Interestingly, when you feed such large language models with an in-domain sentence, they can generate more synthetic sentences, that simulate the domain and linguistic characteristics of the authentic sentence. In the research “&lt;strong&gt;&lt;em&gt;&lt;a href=&quot;https://aclanthology.org/2022.amta-research.2&quot;&gt;Domain-Specific Text Generation for Machine Translation&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;” (Moslem et al., 2022), we investigated the feasibility of this domain-specific text generation technique, when either no or limited bilingual in-domain dataset is available. We proposed a novel approach to domain adaptation leveraging state-of-the-art pre-trained language models to generate huge amounts of synthetic bilingual in-domain data with the goal of improving translation of in-domain texts. The process can be summarised in three simple steps:&lt;/p&gt;

&lt;h4 id=&quot;1-text-generation-target&quot;&gt;1. Text generation (target)&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;Generate target-side synthetic sentences using a large pre-trained language model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When there is a small in-domain translation memory, you can use each target sentence as a prompt to generate text, that simulates the domain characteristics of the authentic in-domain data. If there is no translation memory at all, you can first forward-translate the source text to be translated, or a portion of it, using the baseline MT model.&lt;/p&gt;

&lt;h4 id=&quot;2-back-translation-source&quot;&gt;2. Back-translation (source)&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;Back-translate the synthetic target-side sentences into source language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Combining the idea of in-domain text generation with back-translation, you can generate huge amounts of synthetic bilingual in-domain data, for both use cases.&lt;/p&gt;

&lt;h4 id=&quot;3-mixed-fine-tuning&quot;&gt;3. Mixed fine-tuning&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;Fine-tune the baseline model, on a mix of synthetic and authentic data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, the baseline MT model should be fine-tuned using a combination of the synthetic bilingual in-domain dataset and a randomly sampled section of the original generic dataset.&lt;/p&gt;

&lt;h2 id=&quot;target-text-generation&quot;&gt;Target Text Generation&lt;/h2&gt;

&lt;p&gt;This code snippet shows how to load the GPT-J language model. You can use some efficient loading techniques such &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;float16&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;low_cpu_mem_usage&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;transformers&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPTJForCausalLM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AutoTokenizer&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;torch&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;tokenizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AutoTokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_pretrained&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;EleutherAI/gpt-j-6B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;padding_side&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;left&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pad_token&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eos_token&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;GPTJForCausalLM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_pretrained&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;EleutherAI/gpt-j-6B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                         &lt;span class=&quot;n&quot;&gt;revision&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;float16&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                         &lt;span class=&quot;n&quot;&gt;torch_dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                         &lt;span class=&quot;n&quot;&gt;low_cpu_mem_usage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                         &lt;span class=&quot;n&quot;&gt;cache_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;models_cache/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                         &lt;span class=&quot;n&quot;&gt;pad_token_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eos_token_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;half&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cuda&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Afterwards, you can use each target segment in the authentic in-domain dataset, to generate synthetic in-domain text. We use top-K and top-p sampling to generate diverse text sequences. Here, we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;num_return_sequences&lt;/code&gt; to generate 5 sequences. Each sequence might include multiple sentences. You can then split these text sequences into several sentences using any sentence splitter.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;target_segment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;I am an example sentence that talks about something very specialized!&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;input_ids&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_segment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add_special_tokens&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;return_tensors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cuda&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sample_outputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;do_sample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                &lt;span class=&quot;n&quot;&gt;max_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                &lt;span class=&quot;n&quot;&gt;top_k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                &lt;span class=&quot;n&quot;&gt;top_p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.95&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                &lt;span class=&quot;n&quot;&gt;num_return_sequences&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;early_stopping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;generated_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sample_outputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;skip_special_tokens&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The quality of the language model is important. Here, you can see examples of generated text, that is both linguistically correct, and factually accurate.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In March 2020, India ordered the countrywide shut down of all non-essential economic activities due to the spreading COVID-19 pandemic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;While the overall worldwide economic impact of COVID-19 will only be realized through the end of 2020 and the recovery phase in 2021, it is clear that certain parts of the world have been severely impacted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes, the generated text can be linguistically correct; however, numbers or names might be inaccurate.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Antiviral drugs are approved for pregnant women and should be considered for children younger than &lt;strong&gt;XX&lt;/strong&gt; years, although some are still being investigated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Scientists have found some species of &lt;strong&gt;unicorn&lt;/strong&gt; in Amazon rainforests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If there are only small mistakes, the generated synthetic data can be still used. Obviously, the better the quality of the text generated by the language model, the better the quality we can expect when fine-tuning the baseline MT model on this synthetic data.&lt;/p&gt;

&lt;h2 id=&quot;back-translation&quot;&gt;Back-Translation&lt;/h2&gt;

&lt;p&gt;Now, we have the target side of our new in-domain dataset. To generate the source side, use back-translation, into the other language direction. For back-translation, you can either train another MT model yourself, or use pre-trained models such as &lt;a href=&quot;https://github.com/Helsinki-NLP/Tatoeba-Challenge/blob/master/results/tatoeba-models-all.md&quot;&gt;OPUS models&lt;/a&gt;. Optionally, you can convert OPUS models to the &lt;a href=&quot;https://opennmt.net/CTranslate2/&quot;&gt;CTranslate2&lt;/a&gt; formate with quantisation to enhance efficiency.&lt;/p&gt;

&lt;p&gt;Basically, both the source and target sides of our new large in-domain dataset, consist of synthetic data. The target side is generated by a language model, while the source text is generated by back-translation, in the other language direction.&lt;/p&gt;

&lt;h2 id=&quot;mixed-fine-tuning&quot;&gt;Mixed Fine-Tuning&lt;/h2&gt;

&lt;p&gt;Now, it’s time to apply mixed fine-tuning to the baseline model.&lt;/p&gt;

&lt;p&gt;In other words, continue training our baseline model on a mix of (a) the synthetic bilingual in-domain dataset we obtained from the two previous steps, and (b) a randomly sampled portion of the original generic dataset. In our experiments, we oversampled the synthetic in-domain dataset, by a 9x ratio.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/mixed-fine-tuning-oversampling.png&quot; alt=&quot;Mixed Fine-Tuning Oversampling&quot; /&gt;&lt;/p&gt;

&lt;center&gt;Mixed fine-tuning (Chu et al., 2017)&lt;/center&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;To apply oversampling, we employed the dataset weights feature in OpenNMT-tf. If you are using OpenNMT-py or OpenNMT-tf, you can find more details in this &lt;a href=&quot;https://blog.yasmin.ie/domain-adaptation-mixed-fine-tuning/&quot;&gt;tutorial on mixed fine-tuning&lt;/a&gt; of MT models.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;In both scenarios, our proposed method achieves significant improvements, demonstrated by both automatic and human evaluations. As expected, Setup 1 (when there is a tiny bilingual dataset) reveals better results than Setup 2 (where there is no bilingual dataset at all). Still, models resulted from both setups outperform the baseline model.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/MT-ML-results.png&quot; alt=&quot;Results&quot; /&gt;&lt;/p&gt;

&lt;center&gt;Evaluation results on the in-domain test set, TICO-19&lt;/center&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Previously, synthetic data for machine translation had been created either on the source-side only (forward-translation) or the target side only (back-translation). In some cases, researchers replaced a few words from the source and/or the target with synonyms or similar words. The assumption was that “relevant” monolingual data was available, which was not always the case!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In real-life scenarios&lt;/strong&gt;, things can get more complex. Usually, there is insufficient human-produced data to train or fine-tune high-quality MT systems. Production-level projects can be so specialised, while mining crawled monolingual datasets is inefficient and not necessarily helpful.&lt;/p&gt;

&lt;p&gt;This research work &lt;strong&gt;generates brand new synthetic data on both the source and target sides&lt;/strong&gt;. It employs large language models to put together coherent sentences similar to those to be translated in the current project. Then, the new synthetic data can be used to fine-tune production-level MT systems for domain-specific scenarios.  Feel free to check out our paper, &lt;a href=&quot;https://aclanthology.org/2022.amta-research.2&quot;&gt;&lt;em&gt;Domain-Specific Text Generation for Machine Translation&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;download-scripts&quot;&gt;Download Scripts&lt;/h2&gt;

&lt;p&gt;You can download our scripts and configuration files at &lt;a href=&quot;https://github.com/ymoslem/MT-LM&quot;&gt;GitHub&lt;/a&gt;. If you have applied the method and/or have questions, please let me know.&lt;/p&gt;

&lt;h2 id=&quot;citation&quot;&gt;Citation&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@inproceedings{moslem-etal-2022-domain,
    title = &quot;Domain-Specific Text Generation for Machine Translation&quot;,
    author = &quot;Moslem, Yasmin  and
      Haque, Rejwanul  and
      Kelleher, John  and
      Way, Andy&quot;,
    booktitle = &quot;Proceedings of the 15th biennial conference of the Association for Machine Translation in the Americas (Volume 1: Research Track)&quot;,
    month = sep,
    year = &quot;2022&quot;,
    address = &quot;Orlando, USA&quot;,
    publisher = &quot;Association for Machine Translation in the Americas&quot;,
    url = &quot;https://aclanthology.org/2022.amta-research.2&quot;,
    pages = &quot;14--30&quot;,
    abstract = &quot;Preservation of domain knowledge from the source to target is crucial in any translation workflow. It is common in the translation industry to receive highly specialized projects, where there is hardly any parallel in-domain data. In such scenarios where there is insufficient in-domain data to fine-tune Machine Translation (MT) models, producing translations that are consistent with the relevant context is challenging. In this work, we propose a novel approach to domain adaptation leveraging state-of-the-art pretrained language models (LMs) for domain-specific data augmentation for MT, simulating the domain characteristics of either (a) a small bilingual dataset, or (b) the monolingual source text to be translated. Combining this idea with back-translation, we can generate huge amounts of synthetic bilingual in-domain data for both use cases. For our investigation, we use the state-of-the-art Transformer architecture. We employ mixed fine-tuning to train models that significantly improve translation of in-domain texts. More specifically, in both scenarios, our proposed methods achieve improvements of approximately 5-6 BLEU and 2-3 BLEU, respectively, on the Arabic-to-English and English-to-Arabic language pairs. Furthermore, the outcome of human evaluation corroborates the automatic evaluation results&quot;,
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 12 Dec 2022 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/synthetic-data-machine-translation/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/synthetic-data-machine-translation/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
      <item>
        <title>Translation Auto-suggestions: What do Linguists Think?</title>
        <description>&lt;p&gt;Translation auto-suggestion and auto-completion are among the important features that can help translators better utilize Machine Translation (MT) systems. In a Computer-Aided Translation (CAT) environment, a translator can make use of the MT word auto-suggestion feature as follows:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;typing a few words, or clicking a word in a proposed MT translation, a list of suggestions is displayed.&lt;/li&gt;
  &lt;li&gt;selecting one of the word suggestions from the list, the rest of the translation is modified accordingly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a user survey we designed and distributed via social media networks, we asked participants whether they thought an MT word-level auto-suggestions feature could be helpful, and provided a simple definition and an illustrative image. If their answer was “Yes”, the respondent was asked to specify a reason. By the time of writing this article, we received 41 responses to our survey. While we do not believe this survey is enough to justify introducing an auto-suggestions feature into every MT system, it can be an indicator as to why some users think such a feature could be helpful.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/autosuggest.png&quot; alt=&quot;MT-autosuggestions&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To answer the question, “&lt;em&gt;Which of the following best describes you?&lt;/em&gt;” 46.3% (19) of the respondents chose “&lt;em&gt;Translator/Linguist&lt;/em&gt;”, 31.7% (13) selected “&lt;em&gt;NLP Engineer/Researcher&lt;/em&gt;”, and the rest 22% (9) were other “&lt;em&gt;MT Users&lt;/em&gt;”, not included in the two aforementioned categories.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/autosuggest-categories.png&quot; alt=&quot;users&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Among the respondents to the survey, 90.2% (37) answered “Yes” to the question “&lt;em&gt;In general, do you believe that a word-level auto-suggestions feature is helpful?&lt;/em&gt;” The figure below shows the breakdown of answers to the question, “&lt;em&gt;Why do you believe that a word-level auto-suggestions feature can be helpful?&lt;/em&gt;” taking into consideration those who answered “No” to the previous question.&lt;/p&gt;

&lt;p&gt;Out of the 37 persons who believed a word-level auto-suggestions feature can be helpful, 40.5% (15) of the respondents specified that it can give them some inspiration. This answer is specifically interesting as it is not constrained by time-saving benefits; hence, it focusses more on effectiveness rather than efficiency. The respondent that answered with “Other” mentioned that it allows them to look for alternative senses or phrasings, especially when they suspect the initial translation is bad, and referred to this as “human in the loop”.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/autosuggest-why.png&quot; alt=&quot;autosuggest-why&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Respondents were allowed to give extra comments; among the notable comments were:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;small&gt;I think word-level suggestions can be a useful feature, particularly when the target language can have several translations of a single source word.&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;small&gt;Word-level suggestions can be helpful, but sometimes you end up spending a lot of time figuring out if the MT suggestion is a valid translation in that context. So, I’m not really sure yet how I feel about it.&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;small&gt;It’s useful, as long as it’s seen as a suggestion, and not inserted in the target where the translator is typing.&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Among the respondents who answered “For me, it is easier or faster than typing”, comments included:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;small&gt;Though most of the time; the suggestions are lousy.&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;small&gt;I don’t think it gives me inspiration as I mostly need it for structures, not single words.&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;small&gt;Auto-suggestion does not have to come from machine translation. History is much more useful.&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The last comment above might be referring to the fact that in some CAT tools, auto-suggestions can also include glossary terms, and translation memory sub-segments, which encourages further research efforts to investigate methods to enhance leveraging and interaction between various translation resources in human-in-the-loop environments.&lt;/p&gt;

&lt;p&gt;We hope this survey will inspire future user studies to look deeper into how diverse users of MT and CAT tools prefer to utilize certain features, such as auto-suggestions, and the value they seek. More aspects should be taken into consideration such as language pairs, translation workflows, and user interfaces. This can help improve these features to better support linguists and other MT users and boost their productivity as well as translation quality.&lt;/p&gt;

&lt;h3 id=&quot;citation&quot;&gt;Citation&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@inproceedings{moslem2022-autosuggest,
    title = &quot;Word-Level Auto-Completion: What can we achieve out of the box?&quot;,
    author = &quot;Moslem, Yasmin  and
      Haque, Rejwanul  and
      Way, Andy&quot;,
    booktitle = &quot;In Proceedings of the Seventh Conference on Machine Translation&quot;,
    month = Dec,
    year = &quot;2022&quot;,
    address = &quot;Abu Dhabi, UAE&quot;,
    publisher = &quot;Association for Computational Linguistics&quot;,
    url = &quot;https://arxiv.org/abs/2210.12802&quot;,
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Mon, 24 Oct 2022 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/translation-autosuggestion-survey/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/translation-autosuggestion-survey/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
      <item>
        <title>Machine Translation Robustness</title>
        <description>&lt;p&gt;Let’s talk briefly about the concept of “Robustness” of neural machine translation (NMT) systems. While robustness should be emphasized when building any NMT system, even high-resource languages with plenty of data can still face linguistic challenges.&lt;/p&gt;

&lt;h2 id=&quot;what-does-nmt-robustness-mean&quot;&gt;What does NMT “Robustness” mean?&lt;/h2&gt;

&lt;p&gt;It simply means that a certain NMT engine can handle a specific linguistic feature, found in the input to be translated. This feature might not be naturally occurring in the training data. Among examples of linguistic features we want our NMT model to be robust while translating are: domain terminology, proper names, number formats, text case, misspellings, code switching (between two languages), and untranslatables such as tags, email addresses, etc.&lt;/p&gt;

&lt;h2 id=&quot;how-can-we-improve-nmt-robustness&quot;&gt;How can we improve NMT robustness?&lt;/h2&gt;

&lt;p&gt;The first step to machine translation robustness is defining the issues that your model frequently encounters when translating a certain type of text. This step is underestimated, and in my opinion it is a sign of the maturity of production-level operations.&lt;/p&gt;

&lt;p&gt;This goes beyond numerical human evaluation, and moves a step further towards defining specific types of issues. In simple words, human evaluators are asked to mention a clear reason why they think a translation should be ranked as 3 out of 5, for example. At the beginning, they might be provided with common lists, but they should also have the option to add more issues, that can be integrated into that list later. Such explanations should not be vague; they should be precise in a way allowing MT engineers to fix these issues. Problematic words should be marked; sometimes the track-changes feature is used. The main question is: &lt;em&gt;What is the most critical issue in this translation?&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-can-we-improve-nmt-robustness-1&quot;&gt;How can we improve NMT “Robustness”?&lt;/h2&gt;

&lt;p&gt;In the findings of the WMT2020 Robustness Shared Task, under the “Common Trends” section, Specia et al. (2020) stated: “Participating systems were trained following a standard recipe, i) using big-transformer models, ii) boosting performance with tagged back-translation, iii) continued training with filtered data and in-domain data (where available), iv) ensembling different models to obtain further improvements.”&lt;/p&gt;

&lt;p&gt;In this sense, data augmentation techniques can be helpful, and then you integrate this new data into the NMT system, via combining or fine-tuning.&lt;/p&gt;

&lt;p&gt;As training a new system frequently might not be feasible, it is common in some companies to temporarily apply on-the-fly find-replace operations on translations, until the next training is possible. Some researchers also suggest making such on-the-fly handling easier by injecting the training data with certain placeholders, to be able to replace later. To apply this, in a portion of the training data, natural tags (html, xml, long numbers, etc.) are replaced with pseudo-tags (e.g. &amp;lt;t0&amp;gt;, &amp;lt;t1&amp;gt;, &amp;lt;t2&amp;gt;, …). These pseudo-tags should be also added as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user_defined_symbols&lt;/code&gt; to the SentencePiece model (cf. SPM &lt;a href=&quot;https://github.com/google/sentencepiece/blob/master/doc/options.md&quot;&gt;options&lt;/a&gt;). At inference time, it is easy to define and replace these tags with untraslatables during pre-processing and post-processing steps. On a relevant note, activating the SentencePiece option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;split_digits&lt;/code&gt; helps with copying longer numbers without intervention, while the option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;byte_fallback&lt;/code&gt; sometimes helps with irregular characters in the training data.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://themqm.org/&quot;&gt;MQM&lt;/a&gt; - Multidimensional Quality Metrics (&lt;a href=&quot;https://aclanthology.org/2013.tc-1.6/&quot;&gt;Lommel et al., 2013&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Training Neural Machine Translation to Apply Terminology Constraints (&lt;a href=&quot;https://aclanthology.org/P19-1294/&quot;&gt;Dinu et al., 2019&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Improving Robustness in Real-World Neural Machine Translation Engines (&lt;a href=&quot;https://aclanthology.org/W19-6727/&quot;&gt;Gupta et al., 2019&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;How Should Markup Tags Be Translated? (&lt;a href=&quot;https://aclanthology.org/2020.wmt-1.138/&quot;&gt;Hanneman and Dinu, 2020&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Evaluating Robustness to Input Perturbations for Neural Machine Translation (&lt;a href=&quot;https://arxiv.org/abs/2005.00580&quot;&gt;Niu et al., 2020&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Findings of the WMT 2020 Shared Task on Machine Translation Robustness (&lt;a href=&quot;https://aclanthology.org/2020.wmt-1.4/&quot;&gt;Specia et al., 2020&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Business Critical Errors: A Framework for Adaptive Quality Feedback (&lt;a href=&quot;https://aclanthology.org/2022.amta-upg.17/&quot;&gt;Stewart et al., 2022&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Improve MT for Search with Selected Translation Memory using Search Signals (&lt;a href=&quot;https://aclanthology.org/2022.amta-upg.9/&quot;&gt;Zhang 2022&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 28 Sep 2022 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/machine-translation-robustness/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/machine-translation-robustness/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
      <item>
        <title>Machine Translation Models: How to Build and Deploy</title>
        <description>&lt;p&gt;This is a Neural Machine Translation (NMT) tutorial with &lt;a href=&quot;https://github.com/ymoslem/OpenNMT-py&quot;&gt;OpenNMT-py&lt;/a&gt; and relevant tools. It covers data preprocessing, model training, evaluation, and deployment. The tutorial was put together as part of a mentorship activity I organised in 2022.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/ymoslem/OpenNMT-Tutorial&quot;&gt;&lt;img src=&quot;https://github-readme-stats.vercel.app/api/pin/?theme=graywhite&amp;amp;username=ymoslem&amp;amp;repo=OpenNMT-Tutorial&quot; alt=&quot;NMT-tutorial&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;fundamentals&quot;&gt;Fundamentals&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Data Processing (&lt;a href=&quot;1-NMT-Data-Processing.ipynb&quot;&gt;notebook&lt;/a&gt;, &lt;a href=&quot;https://github.com/ymoslem/MT-Preparation&quot;&gt;repository&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;NMT Model Training with OpenNMT-py (&lt;a href=&quot;2-NMT-Training.ipynb&quot;&gt;notebook&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Translation/Inference with CTranslate2 (&lt;a href=&quot;https://gist.github.com/ymoslem/60e1d1dc44fe006f67e130b6ad703c4b&quot;&gt;code&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;MT Evaluation with BLEU (&lt;a href=&quot;https://blog.yasmin.ie/compute-bleu-score/&quot;&gt;tutorial&lt;/a&gt;, &lt;a href=&quot;https://github.com/ymoslem/MT-Evaluation&quot;&gt;repository&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Simple Web UI (&lt;a href=&quot;https://blog.yasmin.ie/nmt-web-interface/&quot;&gt;tutorial&lt;/a&gt;, &lt;a href=&quot;https://github.com/ymoslem/OpenNMT-Web-Interface&quot;&gt;repository&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;advanced-topics&quot;&gt;Advanced Topics&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Running TensorBoard with OpenNMT (&lt;a href=&quot;https://blog.yasmin.ie/TensorBoard/&quot;&gt;tutorial&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Low-Resource Neural Machine Translation (&lt;a href=&quot;https://blog.yasmin.ie/low-resource-nmt/&quot;&gt;tutorial&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Domain Adaptation with Mixed Fine-tuning (&lt;a href=&quot;https://blog.yasmin.ie/domain-adaptation-mixed-fine-tuning/&quot;&gt;tutorial&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Overview of Domain Adaptation Techniques (&lt;a href=&quot;https://amtaweb.org/wp-content/uploads/2020/11/NMTDomainAdaptationTechniques.pdf&quot;&gt;tutorial&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Multilingual Machine Translation (&lt;a href=&quot;https://blog.yasmin.ie/multilingual-nmt/&quot;&gt;tutorial&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Using Pre-trained NMT models with CTranslate2 (&lt;a href=&quot;https://gist.github.com/ymoslem/a414a0ead0d3e50f4d7ff7110b1d1c0d&quot;&gt;tutorial&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 15 Mar 2022 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/OpenNMT-tutorial/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/OpenNMT-tutorial/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
      <item>
        <title>Mixed Fine-Tuning - Domain Adaptation That Works!</title>
        <description>&lt;p&gt;Training a robust generic model is an interesting task. However, when you want to customize your Machine Translation model to observe the terminology and style of a certain domain or client, Domain Adaptation comes to life. In previous posts, we discussed several approaches to Domain Adaptation. In this post, we are going to concentrate on a very effective approach called &lt;strong&gt;Mixed Fine-Tuning&lt;/strong&gt;, originally proposed by &lt;a href=&quot;https://aclanthology.org/P17-2061/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Chu et al., 2017&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Regular fine-tuning of an NMT model usually consists of two steps:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Building a baseline NMT model, e.g. a generic model.&lt;/li&gt;
  &lt;li&gt;Continuing training the baseline NMT model on an in-domain dataset.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, fine-tuning in this way can lead to “catastrophic forgetting”, i.e. the model overfits the in-domain data, starts forgetting the information learned from the baseline data, and loses generalization. So in practice, when you compare its quality to the baseline model, the in-domain model would give a better BLEU score and human evaluation for translation of sentences very similar to the in-domain training dataset, but worse BLEU score for out-of-domain sentences or even new in-domain sentences.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Unlike plain fine-tuning, in the Mixed Fine-Tuning approach (Chu et al., 2017), you randomly sample a portion from the generic data you used to train the baseline model, and use it during the fine-tuning step along with the in-domain dataset. Over-sampling the in-domain data is the main trick.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The training procedure of the Mixed Fine-tuning approach is as follows:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Train a baseline NMT model on out-of-domain data until convergence.&lt;/li&gt;
  &lt;li&gt;Continue training the NMT baseline model on a &lt;em&gt;mix&lt;/em&gt; of in-domain and out-of-domain data (by &lt;em&gt;oversampling&lt;/em&gt; the in-domain data) until convergence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In NMT tools, such as OpenNMT and MarianMT, &lt;em&gt;dataset weights&lt;/em&gt; can be used to replicate over-sampling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dataset Counts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Generic Dataset: 1,000,000 sentences&lt;/li&gt;
  &lt;li&gt;In-domain Dataset: 100,000 sentences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use weights 1:10 so that the training takes 1 sentence from the bigger generic dataset, and 10 sentences from the smaller in-domain dataset.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Generic Dataset: 1&lt;/li&gt;
  &lt;li&gt;In-domain Dataset: 10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this example, we sequentially sample 1 example from the “Generic Dataset” and 10 examples from the “In-domain Dataset” and so on. By giving the “In-domain Dataset” a higher weight, the model can learn the style and terminology from the in-domain dataset while still be able to generalize, i.e. output high-quality translations for out-of-domain sentences.&lt;/p&gt;

&lt;p&gt;Setting the dataset weights differs from one tool to another. In &lt;a href=&quot;https://opennmt.net/OpenNMT-py/FAQ.html#how-can-i-weight-different-corpora-at-training&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OpenNMT-py&lt;/a&gt;, dataset weights are set as numbers as in the aforementioned example. In &lt;a href=&quot;https://opennmt.net/OpenNMT-tf/data.html?highlight=weighted#weighted-dataset&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OpenNMT-tf&lt;/a&gt;, dataset weights are set as ratios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further notes on the Mixed Fine-tuning approach&lt;/strong&gt; (feel free to experiment with something different, though!)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The approach works well for in-domain datasets between 50k and 500k. For very small in-domain datasets, this approach might &lt;em&gt;not&lt;/em&gt; work well; for bigger in-domain datasets, you might want to try different weights; and for very big in-domain datasets, you can just use the in-domain dataset only, but enrich it with missing aspects like shorter sentences, if needed.&lt;/li&gt;
  &lt;li&gt;If your baseline training data is too big, you randomly extract 10 times the size of the in-domain data.&lt;/li&gt;
  &lt;li&gt;If both the generic and in-domain data are available before training the baseline, we build the vocabulary and SentencePiece models on all datasets, both generic and in-domain datasets.&lt;/li&gt;
  &lt;li&gt;During fine-tuning, we extract a dev/validation dataset from the in-domain dataset only.&lt;/li&gt;
  &lt;li&gt;After fine-tuning, we use two test datasets, one that we used for the out-of-domain baseline, and one extracted from the in-domain dataset, to make sure the model works in both cases.&lt;/li&gt;
  &lt;li&gt;To alleviate “catastrophic forgetting” on generic data, consider averaging the baseline model with the fine-tuned model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among the advantages of the Mixed Fine-tuning approach is that this fine-tuned NMT in-domain model still works well on both unseen in-domain data and general/out-of-domain data. Moreover, the approach can be fully automated (e.g. for various clients) once you verify it for your use cases.&lt;/p&gt;

&lt;p&gt;It is worth mentioning that we have successfully applied the Mixed Fine-Tuning approach, proposed by Chu et al. (2017), in production-level scenarios in the industry. We also employed it in a number of our Domain Adaptation and Low-Resource NMT papers such as &lt;a href=&quot;https://aclanthology.org/2020.icon-adapmt.4/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Haque et al. (2020)&lt;/a&gt; in combination with other approaches, through which we achieved the first place at ICON 2020 shared task, as well as &lt;a href=&quot;https://aclanthology.org/2022.amta-research.2/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Moslem et al. (2022)&lt;/a&gt; where we used synthetic in-domain data.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Axelrod, A., He, X., &amp;amp; Gao, J. (2011). Domain Adaptation via Pseudo In-Domain Data Selection. &lt;em&gt;Proceedings of the 2011 Conference on Empirical Methods in Natural Language Processing&lt;/em&gt;, 355–362. &lt;a href=&quot;https://aclanthology.org/D11-1033&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aclanthology.org/D11-1033&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Chinea-Ríos, M., Peris, Á., &amp;amp; Casacuberta, F. (2017). Adapting Neural Machine Translation with Parallel Synthetic Data. &lt;em&gt;Proceedings of the Second Conference on Machine Translation&lt;/em&gt;, 138–147. &lt;a href=&quot;https://doi.org/10.18653/v1/W17-4714&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/W17-4714&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Chu, C., Dabre, R., &amp;amp; Kurohashi, S. (2017). An Empirical Comparison of Domain Adaptation Methods for Neural Machine Translation. Proceedings of the 55th Annual Meeting of the Association for Computational Linguistics (Volume 2: Short Papers), 385–391. &lt;a href=&quot;https://doi.org/10.18653/v1/P17-2061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/P17-2061&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Freitag, M., &amp;amp; Al-Onaizan, Y. (2016). Fast Domain Adaptation for Neural Machine Translation. In &lt;em&gt;arXiv [cs.CL]&lt;/em&gt;. arXiv. &lt;a href=&quot;http://arxiv.org/abs/1612.06897&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://arxiv.org/abs/1612.06897&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Haque, R., Moslem, Y., &amp;amp; Way, A. (2020). Terminology-Aware Sentence Mining for NMT Domain Adaptation: ADAPT’s Submission to the Adap-MT 2020 English-to-Hindi AI Translation Shared Task. Proceedings of the 17th International Conference on Natural Language Processing (ICON): Adap-MT 2020 Shared Task, 17–23. &lt;a href=&quot;https://aclanthology.org/2020.icon-adapmt.4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aclanthology.org/2020.icon-adapmt.4&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Kobus, C., Crego, J., &amp;amp; Senellart, J. (2017). Domain Control for Neural Machine Translation. &lt;em&gt;Proceedings of Recent Advances in Natural Language Processing&lt;/em&gt;, 372–378. &lt;a href=&quot;http://arxiv.org/abs/1612.06140&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://arxiv.org/abs/1612.06140&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Luong, M.-T., &amp;amp; Manning, C. 2015. Stanford neural machine translation systems for spoken language domains. &lt;em&gt;Proceedings of the 12th International Workshop on Spoken Language Translation: Evaluation Campaign&lt;/em&gt;, 76–79. &lt;a href=&quot;https://aclanthology.org/2015.iwslt-evaluation.11&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aclanthology.org/2015.iwslt-evaluation.11&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Moslem, Y., Haque, R., Kelleher, J., &amp;amp; Way, A. (2022). Domain-Specific Text Generation for Machine Translation. &lt;em&gt;Proceedings of the 15th Biennial Conference of the Association for Machine Translation in the Americas (Volume 1: Research Track)&lt;/em&gt;, 14–30. &lt;a href=&quot;https://aclanthology.org/2022.amta-research.2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aclanthology.org/2022.amta-research.2&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Moslem, Y. (2024). Language Modelling Approaches to Adaptive Machine Translation. In &lt;em&gt;arXiv [cs.CL]&lt;/em&gt;. arXiv. &lt;a href=&quot;http://arxiv.org/abs/2401.14559&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://arxiv.org/abs/2401.14559&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Saunders, D. (2022). Domain Adaptation and Multi-Domain Adaptation for Neural Machine Translation: A Survey. &lt;em&gt;Journal of Artificial Intelligence Research&lt;/em&gt;, &lt;em&gt;75&lt;/em&gt;, 351–424. &lt;a href=&quot;https://doi.org/10.1613/jair.1.13566&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.1613/jair.1.13566&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Sennrich, R., Haddow, B., &amp;amp; Birch, A. (2016a). Controlling Politeness in Neural Machine Translation via Side Constraints. &lt;em&gt;Proceedings of the 2016 Conference of the North AMerican Chapter of the Association for Computational Linguistics: Human Language Technologies&lt;/em&gt;, 35–40. &lt;a href=&quot;https://doi.org/10.18653/v1/N16-1005&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/N16-1005&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Sennrich, R., Haddow, B., &amp;amp; Birch, A. (2016b). Improving Neural Machine Translation Models with Monolingual Data. &lt;em&gt;Proceedings of the 54th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)&lt;/em&gt;, 86–96. &lt;a href=&quot;https://doi.org/10.18653/v1/P16-1009&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/P16-1009&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 06 Jan 2022 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/domain-adaptation-mixed-fine-tuning/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/domain-adaptation-mixed-fine-tuning/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
      <item>
        <title>Notes on Multilingual Machine Translation</title>
        <description>&lt;p&gt;Multilingual NMT is featured by its scalability between any number of languages, instead of having to build individual models. MNMT systems are also desirable because training models with data from diverse language pairs might help a low-resource language acquire extra knowledge from other languages. Moreover, MNMT systems tend to generalize better due to exposure to diverse languages, leading to improved translation quality compared to bilingual NMT systems. This particular phenomenon is known as translation Transfer Learning or Knowledge Transfer (Dabre et al., 2020).&lt;/p&gt;

&lt;h2 id=&quot;tips-for-training-multilingual-nmt-models&quot;&gt;Tips for training multilingual NMT models&lt;/h2&gt;

&lt;p&gt;Building a many-to-one MT system that translates from several languages to one language is simple: just merge all the datasets. Here is an illustration of how your data should look like. Afterwards, it is recommended to shuffle your dataset.&lt;/p&gt;

&lt;hr /&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Source&lt;/th&gt;
      &lt;th&gt;Target&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;ar&amp;gt; Thank you very much&lt;/td&gt;
      &lt;td&gt;شكرا جزيلا&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;es&amp;gt; Thank you very much&lt;/td&gt;
      &lt;td&gt;Muchas gracias&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;fr&amp;gt; Thank you very much&lt;/td&gt;
      &lt;td&gt;Merci beaucoup&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;hi&amp;gt; Thank you very much&lt;/td&gt;
      &lt;td&gt;आपका बहुत बहुत धन्यवाद&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;ar&amp;gt; आपका बहुत बहुत धन्यवाद          &lt;/td&gt;
      &lt;td&gt;شكرا جزيلا&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;en&amp;gt; आपका बहुत बहुत धन्यवाद&lt;/td&gt;
      &lt;td&gt;Thank you very much&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;es&amp;gt; आपका बहुत बहुत धन्यवाद&lt;/td&gt;
      &lt;td&gt;Muchas gracias&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;fr&amp;gt; आपका बहुत बहुत धन्यवाद&lt;/td&gt;
      &lt;td&gt;Merci beaucoup&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;ar&amp;gt; Muchas gracias&lt;/td&gt;
      &lt;td&gt;شكرا جزيلا&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;en&amp;gt; Muchas gracias&lt;/td&gt;
      &lt;td&gt;Thank you very much&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;fr&amp;gt; Muchas gracias&lt;/td&gt;
      &lt;td&gt;Merci beaucoup&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;hi&amp;gt; Muchas gracias&lt;/td&gt;
      &lt;td&gt;आपका बहुत बहुत धन्यवाद&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;en&amp;gt; شكرا جزيلا&lt;/td&gt;
      &lt;td&gt;Thank you very much&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;es&amp;gt; شكرا جزيلا&lt;/td&gt;
      &lt;td&gt;Muchas gracias&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;fr&amp;gt; شكرا جزيلا&lt;/td&gt;
      &lt;td&gt;Merci beaucoup&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;hi&amp;gt; شكرا جزيلا&lt;/td&gt;
      &lt;td&gt;आपका बहुत बहुत धन्यवाद&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;ar&amp;gt; Merci beaucoup&lt;/td&gt;
      &lt;td&gt;شكرا جزيلا&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;en&amp;gt; Merci beaucoup&lt;/td&gt;
      &lt;td&gt;Thank you very much&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;es&amp;gt; Merci beaucoup&lt;/td&gt;
      &lt;td&gt;Muchas gracias&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&amp;lt;hi&amp;gt; Merci beaucoup&lt;/td&gt;
      &lt;td&gt;आपका बहुत बहुत धन्यवाद&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;p&gt;There are a few important points to take into consideration while building multilingual models:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If the data is clearly unbalanced, like you have 75 million sentences for Spanish and 15 million sentences for Portuguese, you have to balance it; otherwise, you would end up with a system that translates Spanish better than Portuguese. This technique is called over-sampling (or up-sampling). The obvious way to achieve it in NMT toolkits is through giving &lt;strong&gt;weights&lt;/strong&gt; to your datasets. In this example, the Spanish dataset can take the weight of 1 while the Portuguese can take the weight of 5 because your Spanish dataset is 5 times larger than your Portuguese dataset.&lt;/li&gt;
  &lt;li&gt;Some papers suggest adding a special token to the start of each sentence. For example, you can start Spanish sentences with the token &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;es&amp;gt;&lt;/code&gt; and Portuguese sentences with the token &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;pt&amp;gt;&lt;/code&gt;. In this case, you will have to add these tokens to your SentencePiece model through the option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--user_defined_symbols&lt;/code&gt;. However, some researchers believe this step is optional.&lt;/li&gt;
  &lt;li&gt;Multilingual NMT models are more useful for low-resource languages than they are for rich-resource languages. Still, low-resource languages that share some linguistic characteristics with other rich-resource languages can benefit from coexistence in one multilingual model. In this sense, multilingual NMT can be considered one of “Transfer Learning” approaches (Tras et al., 2021 and Ding et al., 2021).&lt;/li&gt;
  &lt;li&gt;Languages that do not share the same alphabet cannot achieve the same linguistic benefits from a multilingual NMT model. Still, researchers investigate approaches like &lt;em&gt;transliteration&lt;/em&gt; to increase knowledge transfer between languages that belong to the same language family, but use different alphabets. For example, using this &lt;em&gt;transliteration&lt;/em&gt; trick, my &lt;a href=&quot;https://www.machinetranslation.io/&quot;&gt;Indic-to-English multilingual NMT model&lt;/a&gt; can translate from 10 Indic languages to English.&lt;/li&gt;
  &lt;li&gt;Integrating other data augmentation approaches like &lt;a href=&quot;https://blog.yasmin.ie/low-resource-nmt/&quot;&gt;Back-Translation&lt;/a&gt; can still be useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;using-pre-trained-nmt-models&quot;&gt;Using pre-trained NMT models&lt;/h2&gt;

&lt;p&gt;What about pre-trained multilingual NMT models like mBART (Liu et al., 2020) and M2M-100 (Fan et al., 2020); when to use them? The simple answer is, for low-resource languages (e.g. a few thousands to a few millions, up to 15m), using directly or fine-tuning mBART can give better results. For high-resource languages, training a baseline model from scratch can outperform mBART. Then, applying mixed fine-tuning (Chu et al., 2017) on this new baseline using in-house data can even achieve better gains in terms of Machine Translation quality. Check this &lt;a href=&quot;https://gist.github.com/ymoslem/d85b55d2182cfd2ab5d08bed6c63c713&quot;&gt;code snippet&lt;/a&gt; if you would like to try mBART. You can also convert M2M-100 model to the CTranslate2 format for better efficiency as explained &lt;a href=&quot;https://gist.github.com/ymoslem/a414a0ead0d3e50f4d7ff7110b1d1c0d&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/abs/10.1145/3406095&quot;&gt;A Survey of Multilingual Neural Machine Translation, Dabre et al., 2020&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://aclanthology.org/2020.tacl-1.47/&quot;&gt;Multilingual Denoising Pre-training for Neural Machine Translation, Liu et al., 2020&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2109.10465&quot;&gt;Scalable and Efficient MoE Training for Multitask Multilingual Models, Kem et al., 2021&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://aclanthology.org/2021.nodalida-main.5/&quot;&gt;Extremely low-resource machine translation for closely related languages, Tras et al., 2021&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://aclanthology.org/2021.emnlp-main.263/&quot;&gt;Improving Neural Machine Translation by Bidirectional Training, Ding et al., 2021&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 04 Dec 2021 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/multilingual-nmt/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/multilingual-nmt/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
      <item>
        <title>Low-Resource Neural Machine Translation</title>
        <description>&lt;p&gt;Developing Neural Machine Translation (NMT) models for low-resource languages is a viral topic, both in the industry and academia. In this tutorial, we are going to discuss &lt;strong&gt;tagged back-translation&lt;/strong&gt; as one of the most effective and efficient approaches to training more robust models. Tagged back-translation is not only useful for low-resource languages, but also for other scenarios of data sparsity.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#tagged-back-translation&quot;&gt;Tagged Back-Translation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#lower-casing-vs-true-casing&quot;&gt;Lower-Casing vs. True-Casing&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#sub-wording-to-avoid-unknowns&quot;&gt;Sub-wording to Avoid Unknowns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#shared-vocab-vs-separate-vocab&quot;&gt;Shared Vocab vs. Separate Vocab&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#crawled-data&quot;&gt;Crawled Data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#transfer-learning&quot;&gt;Transfer Learning&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#references&quot;&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tagged-back-translation&quot;&gt;Tagged Back-Translation&lt;/h2&gt;

&lt;p&gt;This approach aims at augmenting the available parallel training data with synthetic data that represent the purpose of the model. Several researchers, including Edunov et al. (2018) and Caswell et al. (2019), have proved that tagged back-translation is very helpful when training NMT models for low-resource languages. Moreover, it can be helpful for rich-resource languages through enriching datasets with specific linguistic features.&lt;/p&gt;

&lt;p&gt;Assuming we want to train an English-to-Hindi NMT mode, the Tagged Back-Translation data augmentation technique depends on the following steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;For an English-to-Hindi model, train another Hindi-to-English model (i.e. in the other direction), using publicly available data from &lt;a href=&quot;https://opus.nlpl.eu/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OPUS&lt;/a&gt;;&lt;/li&gt;
  &lt;li&gt;Select monolingual data in Hindi publicly available (e.g. at &lt;a href=&quot;https://oscar-corpus.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OSCAR&lt;/a&gt;), which must have domains and linguistic features similar to the potential texts to be translated;&lt;/li&gt;
  &lt;li&gt;Use the Hindi-to-English model to create a synthetic dataset, by translating the Hindi monolingual data into English. Note here that only the English side (the source for EN-HI) is MTed while the Hindi side (the target for EN-HI) is human-generated text;&lt;/li&gt;
  &lt;li&gt;Consider using one the available Quality Estimation tools such as &lt;a href=&quot;https://github.com/TharinduDR/TransQuest&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;TransQuest&lt;/a&gt; (Ranasinghe et al., 2020) or &lt;a href=&quot;https://github.com/Unbabel/OpenKiwi&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OpenKiwi&lt;/a&gt; (Kepler et al., 2019) to filter out back-translations of low quality;&lt;/li&gt;
  &lt;li&gt;Add a special tag like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;BT&amp;gt;&lt;/code&gt; to the start of the MTed segments;&lt;/li&gt;
  &lt;li&gt;Build the vocabulary on all the data, both the original and the synthetic datasets;&lt;/li&gt;
  &lt;li&gt;Augment the original English-to-Hindi training dataset with the synthetic dataset;&lt;/li&gt;
  &lt;li&gt;Train a new English-to-Hindi model using the dataset generated from the previous step.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For low-resource languages like Hindi, Haque et al. (2020) showed that the technique works well with 1:1 synthetic to original data. Still, you can experiment with different portions, especially for language pairs of richer resources.&lt;/p&gt;

&lt;p&gt;As demonstrated by Hoang et al. (2018), iterative back-translation for 2-3 runs can improve the quality further. Now, as you have a better Hindi-to-English model, back-translate English monolingual data to train a new version of the English-to-Hindi model. After that, use the new English-to-Hindi model to back-translate the same Hindi monolingual dataset you used for the first run to create a new version of the Hindi-to-English model. The idea here is that you are using a better model to translate the same monolingual data, i.e. without any increase or change, which should result in a better NMT model. Interestingly, you can use both NMT and phrase-based SMT models for back-translation, and then train or fine-tune your baseline NMT system in the required language direction.&lt;/p&gt;

&lt;p&gt;Popel et al. (2010) explored the effect of Block-Backtranslation,  where the training data are presented to the neural network in blocks of authentic parallel data alternated with blocks of synthetic data.&lt;/p&gt;

&lt;h2 id=&quot;lower-casing-vs-true-casing&quot;&gt;Lower-Casing vs. True-Casing&lt;/h2&gt;

&lt;p&gt;For low-resource languages, I prefer lower-casing the data. However, in real-life scenarios or if you are submitting a paper, you are usually required to produce the translation in the true-case. so you can train a truecaser or use sacreMoses’ &lt;a href=&quot;https://github.com/alvations/sacremoses#truecaser&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;truecaser&lt;/a&gt; for English.&lt;/p&gt;

&lt;h2 id=&quot;sub-wording-to-avoid-unknowns&quot;&gt;Sub-wording to Avoid Unknowns&lt;/h2&gt;

&lt;p&gt;To avoid out-of-vocabulary, it is recommended to train your NMT model on subwords instead whole words. Subwording (e.g. BPE or unigram model) is recommended for any type of machine translation model, regardless of whether it is for a low-resource or rich-resource language pair. Among the most popular subwording tools is &lt;a href=&quot;https://github.com/google/sentencepiece&quot;&gt;SentencePiece&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;BT&amp;gt;&lt;/code&gt; for example as the back-translation token, you have to add it to the SentencePiece model through using the option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--user_defined_symbols&lt;/code&gt; during training. The same option can be useful for adding any other special tokens found in your training data, such as tags and non-Latin numbers.&lt;/p&gt;

&lt;p&gt;Consider also using the following SentencePiece options:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--input_sentence_size&lt;/code&gt; to determine maximum number of sentences the trainer loads. This number must be equal to the vocab size;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--shuffle_input_sentence&lt;/code&gt; to shuffle the dataset;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--split_by_number&lt;/code&gt; to split tokens by numbers (0-9); and&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--byte_fallback&lt;/code&gt; to decompose unknown pieces into UTF-8 byte pieces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;shared-vocab-vs-separate-vocab&quot;&gt;Shared Vocab vs. Separate Vocab&lt;/h2&gt;

&lt;p&gt;If both the source and target share some vocabulary, e.g. similar languages and code switching, using shared vocabulary might help. Using shared vocabulary involve two steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Training a SentencePiece model on all datasets for both languages;&lt;/li&gt;
  &lt;li&gt;Using shared vocab instead of separate vocabs while training the NMT model.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;crawled-data&quot;&gt;Crawled Data&lt;/h2&gt;

&lt;p&gt;Currently, OPUS includes some datasets that are crawled from bilingual websites, and then the sentences are matched using multilingual similarity tools such as &lt;a href=&quot;https://github.com/facebookresearch/LASER&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LASER&lt;/a&gt;, &lt;a href=&quot;https://github.com/bojone/labse&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LabSE&lt;/a&gt;, and &lt;a href=&quot;https://github.com/tensorflow/hub/blob/master/examples/colab/cross_lingual_similarity_with_tf_hub_multilingual_universal_encoder.ipynb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;m-USE&lt;/a&gt;. However, according to Kreutzer et al. (2021) crawled datasets suffer from quality issues that can affect the quality of outcome NMT models. Hence, it is important to try filtering them before using, and maybe exclude them from initial baselines.&lt;/p&gt;

&lt;h2 id=&quot;transfer-learning&quot;&gt;Transfer Learning&lt;/h2&gt;

&lt;p&gt;Instead of training a model from scratch, transfer learning can be applied. In this sense, you can use a multilingual model like mBART-50, M2M-100, or NLLB-200, and fine-tune it on your dataset. Moreover, unidirectional models can be used (e.g. &lt;a href=&quot;https://github.com/Helsinki-NLP/Tatoeba-Challenge/tree/master/models&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OPUS&lt;/a&gt;). If your low-resource language is similar to languages supported by such models, it can benefit from shared linguistic features. Back-translation can be used here as well to augment the authentic dataset.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Caswell, I., Chelba, C., &amp;amp; Grangier, D. (2019). Tagged Back-Translation. Proceedings of the Fourth Conference on Machine Translation (Volume 1: Research Papers), 53–63. &lt;a href=&quot;https://doi.org/10.18653/v1/W19-5206&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/W19-5206&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Edunov, S., Ott, M., Auli, M., &amp;amp; Grangier, D. Understanding Back-Translation at Scale. &lt;em&gt;Proceedings of the 2018 Conference on Empirical Methods in Natural Language Processing&lt;/em&gt;, 489–500. &lt;a href=&quot;https://doi.org/10.18653/v1/D18-1045&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/D18-1045&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Gebauer, P., Bojar, O., Švandelík, V., &amp;amp; Popel, M. (2021). CUNI Systems in WMT21: Revisiting Backtranslation Techniques for English-Czech NMT. &lt;em&gt;Proceedings of the Sixth Conference on Machine Translation&lt;/em&gt;, 123–129. &lt;a href=&quot;https://aclanthology.org/2021.wmt-1.7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aclanthology.org/2021.wmt-1.7&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Haque, R., Moslem, Y., &amp;amp; Way, A. (2020). Terminology-Aware Sentence Mining for NMT Domain Adaptation: ADAPT’s Submission to the Adap-MT 2020 English-to-Hindi AI Translation Shared Task. Proceedings of the 17th International Conference on Natural Language Processing (ICON): Adap-MT 2020 Shared Task, 17–23. &lt;a href=&quot;https://aclanthology.org/2020.icon-adapmt.4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aclanthology.org/2020.icon-adapmt.4&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Hoang, V. C. D., Koehn, P., Haffari, G., &amp;amp; Cohn, T. (2018). Iterative Back-Translation for Neural Machine Translation. &lt;em&gt;Proceedings of the 2nd Workshop on Neural Machine Translation and Generation&lt;/em&gt;, 18–24. &lt;a href=&quot;https://doi.org/10.18653/v1/W18-2703&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/W18-2703&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Kreutzer, J., Caswell, I., Wang, L., Wahab, A., van Esch, D., Ulzii-Orshikh, N., Tapo, A., Subramani, N., Sokolov, A., Sikasote, C., Setyawan, M., Sarin, S., Samb, S., Sagot, B., Rivera, C., Rios, A., Papadimitriou, I., Osei, S., Suarez, P. O., … Adeyemi, M. (2022). Quality at a Glance: An Audit of Web-Crawled Multilingual Datasets. &lt;em&gt;Transactions of the Association for Computational Linguistics&lt;/em&gt;, &lt;em&gt;10&lt;/em&gt;, 50–72. &lt;a href=&quot;https://doi.org/10.1162/tacl_a_00447&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.1162/tacl_a_00447&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Popel, M., Tomkova, M., Tomek, J., Kaiser, Ł., Uszkoreit, J., Bojar, O., &amp;amp; Žabokrtský, Z. (2020). Transforming machine translation: a deep learning system reaches news translation quality comparable to human professionals. &lt;em&gt;Nature Communications&lt;/em&gt;, &lt;em&gt;11&lt;/em&gt;(1), 4381. &lt;a href=&quot;https://doi.org/10.1038/s41467-020-18073-9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.1038/s41467-020-18073-9&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Ramírez-Sánchez, G., Zaragoza-Bernabeu, J., Bañón, M., &amp;amp; Rojas, S. O. (2020). &lt;em&gt;Bifixer and Bicleaner: two open-source tools to clean your parallel data&lt;/em&gt;. 291–298. &lt;a href=&quot;https://aclanthology.org/2020.eamt-1.31/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aclanthology.org/2020.eamt-1.31/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Sennrich, R., Haddow, B., &amp;amp; Birch, A. (2016). Improving Neural Machine Translation Models with Monolingual Data. &lt;em&gt;Proceedings of the 54th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)&lt;/em&gt;, 86–96. &lt;a href=&quot;https://doi.org/10.18653/v1/P16-1009&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doi.org/10.18653/v1/P16-1009&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 25 Sep 2021 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/low-resource-nmt/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/low-resource-nmt/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
      <item>
        <title>Web Interface for Machine Translation</title>
        <description>&lt;p&gt;Today, we will create a very simple &lt;strong&gt;Machine Translation (MT) Web Interface&lt;/strong&gt; for &lt;em&gt;OpenNMT-py&lt;/em&gt;, &lt;em&gt;OpenNMT-tf&lt;/em&gt; and &lt;em&gt;FairSeq&lt;/em&gt; models using &lt;em&gt;CTranslate2&lt;/em&gt; and &lt;em&gt;Streamlit&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Previously, there were other tutorials on how to use a &lt;a href=&quot;https://forum.opennmt.net/t/simple-opennmt-py-rest-server/1392&quot;&gt;simple server&lt;/a&gt; and &lt;a href=&quot;https://github.com/ymoslem/OpenNMT-GUI&quot;&gt;web interface with Flask&lt;/a&gt;. However, today’s tutorial is for those who want to create an ultra simple, quick demo.&lt;/p&gt;

&lt;p&gt;We also aim at highlighting that &lt;em&gt;CTranslate2&lt;/em&gt; is now the way to go for serving OpenNMT models due to its exceptional performance. It is completely up to you to use it in a simple way like what we will do here, or to integrate it into a REST API for advanced uses.&lt;/p&gt;

&lt;p&gt;So let’s start…&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Table of Contents:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#objective-simple-machine-translation-web-interface&quot;&gt;Objective: Simple Machine Translation Web Interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#install-requirements&quot;&gt;Install Requirements&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#optional-create-and-activate-a-virtual-environment&quot;&gt;Optional: Create and Activate a Virtual Environment&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#install-required-libraries&quot;&gt;Install Required Libraries&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#convert-model-to-ctranslate2&quot;&gt;Convert Model to CTranslate2&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#ctranslate2-python-sample&quot;&gt;CTranslate2 Example&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#create-your-app&quot;&gt;Create Your App&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#test-app&quot;&gt;Test App&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#translation-app&quot;&gt;Translation App&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#full-code&quot;&gt;Full Code&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#next-steps&quot;&gt;Next Steps&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#streamlit-components&quot;&gt;Streamlit Components&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#deployment&quot;&gt;Deployment&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;objective-simple-machine-translation-web-interface&quot;&gt;Objective: Simple Machine Translation Web Interface&lt;/h2&gt;

&lt;p&gt;Our objective is to develop a simple web interface for Machine Translation like this one.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/streamlit-translate-gui.png&quot; alt=&quot;streamlit-translate-gui&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-requirements&quot;&gt;Install Requirements&lt;/h2&gt;

&lt;h3 id=&quot;optional-create-and-activate-a-virtual-environment&quot;&gt;Optional: Create and Activate a Virtual Environment&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;:
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;virtualenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Create a virtual environment, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myvenv&lt;/code&gt;:
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virtualenv myvenv &lt;span class=&quot;nt&quot;&gt;--python&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;python3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Activate the virtual environment:
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;myvenv/web/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;install-required-libraries&quot;&gt;Install Required Libraries&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;ctranslate2 sentencepiece streamlit watchdog nltk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;convert-model-to-ctranslate2&quot;&gt;Convert Model to CTranslate2&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/OpenNMT/CTranslate2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;CTranslate2&lt;/a&gt; supports both &lt;em&gt;OpenNMT-py&lt;/em&gt; and &lt;em&gt;OpenNMT-tf&lt;/em&gt; models. As of version 2.0, it also supports &lt;em&gt;FairSeq&lt;/em&gt; models. However, you need to convert your model to the &lt;em&gt;CTranslate2&lt;/em&gt; format before using it.&lt;/p&gt;

&lt;p&gt;The following commands are simply copied from the &lt;em&gt;CTranslate2&lt;/em&gt; repository, and tested to make sure they are up-to-date. This example uses pre-trained Transformer English-German models. If you trained your own model, run the same commands on it instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For an OpenNMT-py model:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;OpenNMT-py

wget https://s3.amazonaws.com/opennmt-models/transformer-ende-wmt-pyOnmt.tar.gz
&lt;span class=&quot;nb&quot;&gt;tar &lt;/span&gt;xf transformer-ende-wmt-pyOnmt.tar.gz

ct2-opennmt-py-converter &lt;span class=&quot;nt&quot;&gt;--model_path&lt;/span&gt; averaged-10-epoch.pt &lt;span class=&quot;nt&quot;&gt;--output_dir&lt;/span&gt; ende_ctranslate2 &lt;span class=&quot;nt&quot;&gt;--quantization&lt;/span&gt; int8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;For an OpenNMT-tf model:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;OpenNMT-tf

wget https://s3.amazonaws.com/opennmt-models/averaged-ende-ckpt500k-v2.tar.gz
&lt;span class=&quot;nb&quot;&gt;tar &lt;/span&gt;xf averaged-ende-ckpt500k-v2.tar.gz

ct2-opennmt-tf-converter &lt;span class=&quot;nt&quot;&gt;--model_path&lt;/span&gt; averaged-ende-ckpt500k-v2 &lt;span class=&quot;nt&quot;&gt;--output_dir&lt;/span&gt; ende_ctranslate2 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--src_vocab&lt;/span&gt; averaged-ende-ckpt500k-v2/wmtende.vocab &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--tgt_vocab&lt;/span&gt; averaged-ende-ckpt500k-v2/wmtende.vocab &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--model_type&lt;/span&gt; TransformerBase &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--quantization&lt;/span&gt; int8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;For a FairSeq model:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ct2-fairseq-converterconverter &lt;span class=&quot;nt&quot;&gt;--model_path&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$MODEL&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--data_dir&lt;/span&gt; dict &lt;span class=&quot;nt&quot;&gt;--fixed_dictionary&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DICT&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--output_dir&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$OUTPUT&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--quantization&lt;/span&gt; int8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, we used the option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--quantization int8&lt;/code&gt; to imporve both the size and the performance of the model.&lt;/p&gt;

&lt;h3 id=&quot;ctranslate2-python-sample&quot;&gt;CTranslate2 Python Sample&lt;/h3&gt;

&lt;p&gt;Let’s make sure that &lt;em&gt;CTranslate2&lt;/em&gt; works properly in our setup by running this Python code:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ctranslate2&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctranslate2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ende_ctranslate2/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translate_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;▁H&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;▁world&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translate_batch()&lt;/code&gt; can take a list of sentences and translate them in batches, which would be very efficient. Here we are using only one sentence as an example for demonstration purposes.&lt;/p&gt;

&lt;p&gt;You can also check this detailed example that opens a file and translates it with CTranslate2.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/ymoslem/60e1d1dc44fe006f67e130b6ad703c4b.js&quot;&gt;&lt;/script&gt;

&lt;h2 id=&quot;create-your-app&quot;&gt;Create Your App&lt;/h2&gt;

&lt;h3 id=&quot;test-app&quot;&gt;Test App&lt;/h3&gt;
&lt;p&gt;Let’s first create a small app to see how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Streamlit&lt;/code&gt; works.&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test.py&lt;/code&gt; for example and add the following lines to it.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;streamlit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Upper My Text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Write something and press Enter &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;    to convert it to the UPPER case.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Launch your test app by opening the Terminal and running the following command.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;streamlit run test.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If everything works as expected, you should see something like this in your browser at the URL &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:8501&lt;/code&gt;. Once you type a text and press Enter, the text will be printed in the UPPER case.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/streamlit-test.png&quot; alt=&quot;streamlit-test&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;translation-app&quot;&gt;Translation App&lt;/h2&gt;

&lt;p&gt;Let’s now develop our translation web interface. Create a file called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;translate.py&lt;/code&gt; for example, and add the following to it.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;streamlit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sentencepiece&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spm&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ctranslate2&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;nltk&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sent_tokenize&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Use CTranslate model to translate a sentence

    Args:
        source (str): Source sentences to translate
        translator (object): Object of Translator, with the CTranslate2 model
        sp_source_model (object): Object of SentencePieceProcessor, with the SentencePiece source model
        sp_target_model (object): Object of SentencePieceProcessor, with the SentencePiece target model
    Returns:
        Translation of the source text
    &quot;&quot;&quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;source_sentences&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sent_tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;source_tokenized&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source_sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;translations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translate_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source_tokenized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;translations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tokens&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;translations_detokenized&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translations_detokenized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# [Modify] File paths here to the CTranslate2 SentencePiece models.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ct_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/path/to/the/ctranslate/model/directory&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sp_source_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/path/to/the/sentencepiece/source/model/file&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sp_target_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/path/to/the/sentencepiece/target/model/file&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Create objects of CTranslate2 Translator and SentencePieceProcessor to load the models
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctranslate2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ct_model_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cpu&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# or &quot;cuda&quot; for GPU
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SentencePieceProcessor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp_source_model_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SentencePieceProcessor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp_target_model_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# Title for the page and nice icon
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_page_config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page_title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;NMT&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page_icon&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;🤖&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Header
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Translate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Form to add your items
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my_form&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Textarea to type the source text.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Source Text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_chars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Translate with CTranslate2 model
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Create a button
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;submitted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form_submit_button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Translate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# If the button pressed, print the translation
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Here, we use &quot;st.info&quot;, but you can try &quot;st.write&quot;, &quot;st.code&quot;, or &quot;st.success&quot;.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;submitted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Translation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Make sure you update the variables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ct_model&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sp_source_model&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sp_target_model&lt;/code&gt; with our own paths to the CTranslate2 model, and the SentencePiece source and target models.&lt;/p&gt;

&lt;p&gt;Let’s launch our translator. Run the following command in the Terminal.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;streamlit run translate.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If everything works fine, you should see an output like this at the URL &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:8501/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Try typing a sentence (in the same source language of your model) and press the button “Translate”. The translation should be printed as you see here!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/streamlit-translate.png&quot; alt=&quot;streamlit-translate&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;add-language-pairs&quot;&gt;Add Language Pairs&lt;/h3&gt;

&lt;p&gt;To give your visitor the option to select between multiple language pairs, you can add a dropdown menu like this one.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../static/img/streamlit-dropdown.png&quot; alt=&quot;streamlit-dropdown&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can first change the paths part into a function:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_models&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;English-to-Japanese&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ct_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;path/to/your/ct_model&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sp_source_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;path/to/your/sp_source_model&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sp_target_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;path/to/your/sp_target_model&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Japanese-to-English&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ct_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;path/to/your/ct_model&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sp_source_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;path/to/your/sp_source_model&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sp_target_model_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;path/to/your/sp_target_model&quot;&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctranslate2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ct_model_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SentencePieceProcessor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp_source_model_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SentencePieceProcessor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sp_target_model_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, you change the form to:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my_form&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Dropdown menu to select a language pair
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;selectbox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;Select Language Pair&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;English-to-Japanese&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Japanese-to-English&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#st.write(&apos;You selected:&apos;, option)
&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Textarea to type the source text.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Source Text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_chars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Load models
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;load_models&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# Translate with CTranslate2 model
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_source_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sp_target_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Create a button
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;submitted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;form_submit_button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Translate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# If the button pressed, print the translation
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# Here, we use &quot;st.info&quot;, but you can try &quot;st.write&quot;, &quot;st.code&quot;, or &quot;st.success&quot;.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;submitted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Translation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;translation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;full-code&quot;&gt;Full Code&lt;/h3&gt;

&lt;p&gt;I will be updating &lt;a href=&quot;https://github.com/ymoslem/CTranslate-NMT-Web-Interface&quot;&gt;this repository&lt;/a&gt; with Python samples.&lt;/p&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;

&lt;h3 id=&quot;streamlit-components&quot;&gt;Streamlit Components&lt;/h3&gt;

&lt;p&gt;Streamlit comes with more &lt;a href=&quot;https://streamlit.io/components&quot;&gt;components&lt;/a&gt;. One of the most interesting NLP components you might want to check is &lt;a href=&quot;https://github.com/explosion/spacy-streamlit&quot;&gt;spacy-streamlit&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;deployment&quot;&gt;Deployment&lt;/h3&gt;

&lt;p&gt;You can deploy your app on any service of your choice. However, if you are looking for a free and easy option, consider using &lt;a href=&quot;https://devcenter.heroku.com/articles/getting-started-with-python&quot;&gt;Heroku&lt;/a&gt;. For better performance, test your app with and without Streamlit’s &lt;a href=&quot;https://docs.streamlit.io/en/stable/caching.html&quot;&gt;caching&lt;/a&gt; option and see if it helps.&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you have questions or suggestions, feel free to &lt;a href=&quot;https://blog.yasmin.ie/contact/&quot;&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
        <pubDate>Sun, 25 Jul 2021 00:00:00 +0000</pubDate>
        <link>https://blog.yasmin.ie/nmt-web-interface/</link>
        <guid isPermaLink="true">https://blog.yasmin.ie/nmt-web-interface/</guid>
        
        
        <category>nmt</category>
        
      </item>
    
  </channel>
</rss>
