vince62s: Hello @lamhoangtung can you please fix the flake error so that we can merge this ?
lamhoangtung: @vince62s I just fixed the flake error ^^
diff --git a/onmt/inputters/image_dataset.py b/onmt/inputters/image_dataset.py
index 13fc806a..1a21ae64 100644
--- a/onmt/inputters/image_dataset.py
+++ b/onmt/inputters/image_dataset.py
@@ -75,7 +75,8 @@ class ImageDataReader(DataReaderBase):
                 img = transforms.ToTensor()(
                     Image.fromarray(cv2.imread(img_path, 0)))
             else:
-                img = transforms.ToTensor()(Image.open(img_path))
+                img = Image.open(img_path).convert('RGB')
+                img = transforms.ToTensor()(img)
             if self.truncate and self.truncate != (0, 0):
                 if not (img.size(1) <= self.truncate[0]
                         and img.size(2) <= self.truncate[1]):
diff --git a/onmt/translate/decode_strategy.py b/onmt/translate/decode_strategy.py
index 4f75d87b..b25c3ea1 100644
--- a/onmt/translate/decode_strategy.py
+++ b/onmt/translate/decode_strategy.py
@@ -1,4 +1,5 @@
 import torch
+from copy import deepcopy
 
 
 class DecodeStrategy(object):
@@ -184,7 +185,7 @@ class DecodeStrategy(object):
             # Reordering forbidden_tokens following beam selection
             # We rebuild a dict to ensure we get the value and not the pointer
             forbidden_tokens.append(
-                dict(self.forbidden_tokens[path_idx]))
+                deepcopy(self.forbidden_tokens[path_idx]))
 
             # Grabing the newly selected tokens and associated ngram
             current_ngram = tuple(seq[-n:].tolist())

Alpha channel and grayscale in image-to-text with -image_channel_size=3
For training image to text, the argument `-image_channel_size=3` imply that the images already have the good number of channel. However, some of my images are black and white and saved with only one channel or saved in RGB but with the alpha channel.
I could fix it with a change in `onmt/inputters/image_dataset.py` [here](https://github.com/OpenNMT/OpenNMT-py/blob/master/onmt/inputters/image_dataset.py#L78):

from this:
```
            if self.channel_size == 1:
                img = transforms.ToTensor()(
                    Image.fromarray(cv2.imread(img_path, 0)))
            else:
                img = transforms.ToTensor()(Image.open(img_path))
```
to this:
```
            if self.channel_size == 1:
                img = transforms.ToTensor()(
                    Image.fromarray(cv2.imread(img_path, 0)))
            else:
                img = transforms.ToTensor()(
                    Image.fromarray(cv2.imread(img_path, 1)))
```
The flag in `cv2.imread` with value of 1 tell cv2 to convert to RGB no matter what the original image is.

Should I do a PR ?
diff --git a/onmt/tests/test_beam_search.py b/onmt/tests/test_beam_search.py
index d8a1ddb5..b5a76bfd 100644
--- a/onmt/tests/test_beam_search.py
+++ b/onmt/tests/test_beam_search.py
@@ -61,9 +61,8 @@ class TestBeamSearch(unittest.TestCase):
                     # (but it's still the best score, thus we have
                     # [BLOCKED_SCORE, -inf, -inf, -inf, -inf]
                     expected_scores = torch.tensor(
-                        [0] + [-float('inf')] * (beam_sz - 1))\
-                        .repeat(batch_sz, 1)
-                    expected_scores[:, 0] = self.BLOCKED_SCORE
+                        [self.BLOCKED_SCORE] + [-float('inf')] * (beam_sz - 1)
+                    ).repeat(batch_sz, 1)
                     self.assertTrue(beam.topk_log_probs.equal(expected_scores))
                 else:
                     # repetitions keeps maximizing score
@@ -71,11 +70,9 @@ class TestBeamSearch(unittest.TestCase):
                     # other indexes are -inf so repeating=>BLOCKED_SCORE
                     # which is higher
                     expected_scores = torch.tensor(
-                        [0] + [-float('inf')] * (beam_sz - 1))\
-                        .repeat(batch_sz, 1)
-                    expected_scores[:, :] = self.BLOCKED_SCORE
-                    expected_scores = torch.tensor(
-                        self.BLOCKED_SCORE).repeat(batch_sz, beam_sz)
+                        [self.BLOCKED_SCORE] + [-float('inf')] * (beam_sz - 1)
+                    ).repeat(batch_sz, 1)
+                    self.assertTrue(beam.topk_log_probs.equal(expected_scores))
 
     def test_advance_with_some_repeats_gets_blocked(self):
         # beam 0 and beam >=2 will repeat (beam >= 2 repeat dummy scores)
@@ -137,7 +134,8 @@ class TestBeamSearch(unittest.TestCase):
 
                     expected = torch.full([batch_sz, beam_sz], float("-inf"))
                     expected[:, 0] = no_repeat_score
-                    expected[:, 1:] = self.BLOCKED_SCORE
+                    expected[:, 1:3] = self.BLOCKED_SCORE
+                    expected[:, 3:] = float("-inf")
                     self.assertTrue(
                         beam.topk_log_probs.equal(expected))
 

pip install -e .
parse_log_pytest
requirements.txt
pytest flake8
apt-get update apt-get install -y libsox-dev libsox-fmt-all sox
3.6
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
absl-py==1.4.0
attrs==22.2.0
cachetools==4.2.4
certifi==2021.5.30
charset-normalizer==2.0.12
click==8.0.4
ConfigArgParse==1.7
dataclasses==0.8
flake8==5.0.4
Flask==2.0.3
future==1.0.0
google-auth==2.22.0
google-auth-oauthlib==0.4.6
grpcio==1.48.2
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
itsdangerous==2.0.1
Jinja2==3.0.3
Markdown==3.3.7
MarkupSafe==2.0.1
mccabe==0.7.0
numpy==1.19.5
oauthlib==3.2.2
-e git+https://github.com/OpenNMT/OpenNMT-py.git@60125c807d1cb18099a69dbfba699bcdf30560b1#egg=OpenNMT_py
packaging==21.3
pluggy==1.0.0
protobuf==3.19.6
py==1.11.0
pyasn1==0.5.1
pyasn1-modules==0.3.0
pycodestyle==2.9.1
pyflakes==2.5.0
pyonmttok==1.37.1
pyparsing==3.1.4
pytest==7.0.1
PyYAML==6.0.1
requests==2.27.1
requests-oauthlib==2.0.0
rsa==4.9
six==1.17.0
tensorboard==2.10.1
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.1
tomli==1.2.3
torch==1.10.2
torchtext==0.4.0
tqdm==4.64.1
typing_extensions==4.1.1
urllib3==1.26.20
waitress==2.0.0
Werkzeug==2.0.3
zipp==3.6.0

name: OpenNMT-py
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - absl-py==1.4.0
      - attrs==22.2.0
      - cachetools==4.2.4
      - charset-normalizer==2.0.12
      - click==8.0.4
      - configargparse==1.7
      - dataclasses==0.8
      - flake8==5.0.4
      - flask==2.0.3
      - future==1.0.0
      - google-auth==2.22.0
      - google-auth-oauthlib==0.4.6
      - grpcio==1.48.2
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - itsdangerous==2.0.1
      - jinja2==3.0.3
      - markdown==3.3.7
      - markupsafe==2.0.1
      - mccabe==0.7.0
      - numpy==1.19.5
      - oauthlib==3.2.2
      - packaging==21.3
      - pluggy==1.0.0
      - protobuf==3.19.6
      - py==1.11.0
      - pyasn1==0.5.1
      - pyasn1-modules==0.3.0
      - pycodestyle==2.9.1
      - pyflakes==2.5.0
      - pyonmttok==1.37.1
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pyyaml==6.0.1
      - requests==2.27.1
      - requests-oauthlib==2.0.0
      - rsa==4.9
      - six==1.17.0
      - tensorboard==2.10.1
      - tensorboard-data-server==0.6.1
      - tensorboard-plugin-wit==1.8.1
      - tomli==1.2.3
      - torch==1.10.2
      - torchtext==0.4.0
      - tqdm==4.64.1
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - waitress==2.0.0
      - werkzeug==2.0.3
      - zipp==3.6.0
prefix: /opt/conda/envs/OpenNMT-py

onmt/tests/test_beam_search.py::TestBeamSearch::test_advance_with_all_repeats_gets_blocked onmt/tests/test_beam_search.py::TestBeamSearch::test_advance_with_some_repeats_gets_blocked
onmt/tests/test_beam_search.py::TestBeamSearch::test_beam_is_done_when_n_best_beams_eos_using_min_length onmt/tests/test_beam_search.py::TestBeamSearch::test_beam_returns_attn_with_correct_length onmt/tests/test_beam_search.py::TestBeamSearch::test_doesnt_predict_eos_if_shorter_than_min_len onmt/tests/test_beam_search.py::TestBeamSearch::test_repeating_excluded_index_does_not_die onmt/tests/test_beam_search.py::TestBeamSearchAgainstReferenceCase::test_beam_advance_against_known_reference onmt/tests/test_beam_search.py::TestBeamWithLengthPenalty::test_beam_advance_against_known_reference
onmt/inputters/image_dataset.py onmt/translate/decode_strategy.py
onmt/inputters/image_dataset.py onmt/translate/decode_strategy.py