We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
CI tests are failing on BLEU
CI tests on Master are failing on checking Bleu metric: 

- https://app.circleci.com/pipelines/github/pytorch/ignite/1755/workflows/00c8cfad-8243-4f5f-9e9e-b8eaeee58b17
- https://github.com/pytorch/ignite/actions/runs/725753501

cc @sdesrozis @gucifer 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ignite/metrics/nlp/bleu.py`
Content:
```
1 import math
2 from collections import Counter
3 from typing import Any, Callable, Sequence, Tuple, Union
4 
5 import torch
6 
7 from ignite.exceptions import NotComputableError
8 from ignite.metrics.metric import Metric, reinit__is_reduced, sync_all_reduce
9 from ignite.metrics.nlp.utils import modified_precision
10 
11 __all__ = ["Bleu"]
12 
13 
14 def _closest_ref_length(references: Sequence[Sequence[Any]], hyp_len: int) -> int:
15     ref_lens = (len(reference) for reference in references)
16     closest_ref_len = min(ref_lens, key=lambda ref_len: (abs(ref_len - hyp_len), ref_len))
17     return closest_ref_len
18 
19 
20 class _Smoother:
21     """
22     Smoothing helper
23     http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf
24     """
25 
26     def __init__(self, method: str):
27         valid = ["no_smooth", "smooth1", "nltk_smooth2", "smooth2"]
28         if method not in valid:
29             raise ValueError(f"Smooth is not valid (expected: {valid}, got: {method})")
30         self.smooth = method
31 
32     def __call__(self, numerators: Counter, denominators: Counter) -> Sequence[float]:
33         method = getattr(self, self.smooth)
34         return method(numerators, denominators)
35 
36     @staticmethod
37     def smooth1(numerators: Counter, denominators: Counter) -> Sequence[float]:
38         epsilon = 0.1
39         denominators_ = [max(1, d) for d in denominators.values()]
40         return [n / d if n != 0 else epsilon / d for n, d in zip(numerators.values(), denominators_)]
41 
42     @staticmethod
43     def nltk_smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:
44         denominators_ = [max(1, d) for d in denominators.values()]
45         return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators_)]
46 
47     @staticmethod
48     def smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:
49         return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators.values())]
50 
51     @staticmethod
52     def no_smooth(numerators: Counter, denominators: Counter) -> Sequence[float]:
53         denominators_ = [max(1, d) for d in denominators.values()]
54         return [n / d for n, d in zip(numerators.values(), denominators_)]
55 
56 
57 class Bleu(Metric):
58     r"""Calculates the `BLEU score <https://en.wikipedia.org/wiki/BLEU>`_.
59 
60     .. math::
61        \text{BLEU} = b_{p} \cdot \exp \left( \sum_{n=1}^{N} w_{n} \: \log p_{n} \right)
62 
63     where :math:`N` is the order of n-grams, :math:`b_{p}` is a sentence brevety penalty, :math:`w_{n}` are
64     positive weights summing to one and :math:`p_{n}` are modified n-gram precisions.
65 
66     More details can be found in `Papineni et al. 2002`__.
67 
68     __ https://www.aclweb.org/anthology/P02-1040.pdf
69 
70     In addition, a review of smoothing techniques can be found in `Chen et al. 2014`__
71 
72     __ http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf
73 
74     Remark :
75 
76         This implementation is inspired by nltk
77 
78     Args:
79         ngram: order of n-grams.
80         smooth: enable smoothing. Valid are ``no_smooth``, ``smooth1``, ``nltk_smooth2`` or ``smooth2``.
81             Default: ``no_smooth``.
82         output_transform: a callable that is used to transform the
83             :class:`~ignite.engine.engine.Engine`'s ``process_function``'s output into the
84             form expected by the metric. This can be useful if, for example, you have a multi-output model and
85             you want to compute the metric with respect to one of the outputs.
86             By default, metrics require the output as ``(y_pred, y)`` or ``{'y_pred': y_pred, 'y': y}``.
87         device: specifies which device updates are accumulated on. Setting the
88             metric's device to be the same as your ``update`` arguments ensures the ``update`` method is
89             non-blocking. By default, CPU.
90 
91     Example:
92 
93     .. code-block:: python
94 
95         from ignite.metrics.nlp import Bleu
96 
97         m = Bleu(ngram=4, smooth="smooth1")
98 
99         y_pred = "the the the the the the the"
100         y = ["the cat is on the mat", "there is a cat on the mat"]
101 
102         m.update((y_pred.split(), [y.split()]))
103 
104         print(m.compute())
105 
106     .. versionadded:: 0.5.0
107     """
108 
109     def __init__(
110         self,
111         ngram: int = 4,
112         smooth: str = "no_smooth",
113         output_transform: Callable = lambda x: x,
114         device: Union[str, torch.device] = torch.device("cpu"),
115     ):
116         if ngram <= 0:
117             raise ValueError(f"ngram order must be greater than zero (got: {ngram})")
118         self.ngrams_order = ngram
119         self.weights = [1 / self.ngrams_order] * self.ngrams_order
120         self.smoother = _Smoother(method=smooth)
121         super(Bleu, self).__init__(output_transform=output_transform, device=device)
122 
123     def _corpus_bleu(self, references: Sequence[Sequence[Any]], candidates: Sequence[Sequence[Any]],) -> float:
124         p_numerators: Counter = Counter()
125         p_denominators: Counter = Counter()
126 
127         if len(references) != len(candidates):
128             raise ValueError(
129                 f"nb of candidates should be equal to nb of reference lists ({len(candidates)} != "
130                 f"{len(references)})"
131             )
132 
133         # Iterate through each hypothesis and their corresponding references.
134         for refs, hyp in zip(references, candidates):
135             # For each order of ngram, calculate the numerator and
136             # denominator for the corpus-level modified precision.
137             for i in range(1, self.ngrams_order + 1):
138                 numerator, denominator = modified_precision(refs, hyp, i)
139                 p_numerators[i] += numerator
140                 p_denominators[i] += denominator
141 
142         # Returns 0 if there's no matching n-grams
143         # We only need to check for p_numerators[1] == 0, since if there's
144         # no unigrams, there won't be any higher order ngrams.
145         if p_numerators[1] == 0:
146             return 0
147 
148         # If no smoother, returns 0 if there's at least one a not matching n-grams
149         if self.smoother.smooth == "no_smooth" and min(p_numerators.values()) == 0:
150             return 0
151 
152         # Calculate the hypothesis lengths
153         hyp_lengths = [len(hyp) for hyp in candidates]
154 
155         # Calculate the closest reference lengths.
156         ref_lengths = [_closest_ref_length(refs, hyp_len) for refs, hyp_len in zip(references, hyp_lengths)]
157 
158         # Sum of hypothesis and references lengths
159         hyp_len = sum(hyp_lengths)
160         ref_len = sum(ref_lengths)
161 
162         # Calculate corpus-level brevity penalty.
163         if hyp_len < ref_len:
164             bp = math.exp(1 - ref_len / hyp_len) if hyp_len > 0 else 0.0
165         else:
166             bp = 1.0
167 
168         # Smoothing
169         p_n = self.smoother(p_numerators, p_denominators)
170 
171         # Compute the geometric mean
172         s = [w_i * math.log(p_i) for w_i, p_i in zip(self.weights, p_n)]
173         gm = bp * math.exp(math.fsum(s))
174         return gm
175 
176     @reinit__is_reduced
177     def reset(self) -> None:
178         self._sum_of_bleu = torch.tensor(0.0, dtype=torch.double, device=self._device)
179         self._num_sentences = 0
180 
181     @reinit__is_reduced
182     def update(self, output: Tuple[Sequence[Any], Sequence[Sequence[Any]]]) -> None:
183         y_pred, y = output
184         self._sum_of_bleu += self._corpus_bleu(references=[y], candidates=[y_pred])
185         self._num_sentences += 1
186 
187     @sync_all_reduce("_sum_of_bleu", "_num_sentences")
188     def compute(self) -> torch.Tensor:
189         if self._num_sentences == 0:
190             raise NotComputableError("Bleu must have at least one example before it can be computed.")
191         return self._sum_of_bleu / self._num_sentences
192
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ignite/metrics/nlp/bleu.py b/ignite/metrics/nlp/bleu.py
--- a/ignite/metrics/nlp/bleu.py
+++ b/ignite/metrics/nlp/bleu.py
@@ -1,6 +1,6 @@
 import math
 from collections import Counter
-from typing import Any, Callable, Sequence, Tuple, Union
+from typing import Any, Callable, Sequence, Tuple, Union, ValuesView
 
 import torch
 
@@ -42,11 +42,17 @@
     @staticmethod
     def nltk_smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:
         denominators_ = [max(1, d) for d in denominators.values()]
-        return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators_)]
+        return _Smoother._smooth2(numerators.values(), denominators_)
 
     @staticmethod
     def smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:
-        return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators.values())]
+        return _Smoother._smooth2(numerators.values(), denominators.values())
+
+    @staticmethod
+    def _smooth2(
+        numerators: Union[ValuesView[int], Sequence[int]], denominators: Union[ValuesView[int], Sequence[int]]
+    ) -> Sequence[float]:
+        return [(n + 1) / (d + 1) if i != 0 else n / d for i, (n, d) in enumerate(zip(numerators, denominators))]
 
     @staticmethod
     def no_smooth(numerators: Counter, denominators: Counter) -> Sequence[float]:

{"golden_diff": "diff --git a/ignite/metrics/nlp/bleu.py b/ignite/metrics/nlp/bleu.py\n--- a/ignite/metrics/nlp/bleu.py\n+++ b/ignite/metrics/nlp/bleu.py\n@@ -1,6 +1,6 @@\n import math\n from collections import Counter\n-from typing import Any, Callable, Sequence, Tuple, Union\n+from typing import Any, Callable, Sequence, Tuple, Union, ValuesView\n \n import torch\n \n@@ -42,11 +42,17 @@\n     @staticmethod\n     def nltk_smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:\n         denominators_ = [max(1, d) for d in denominators.values()]\n-        return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators_)]\n+        return _Smoother._smooth2(numerators.values(), denominators_)\n \n     @staticmethod\n     def smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:\n-        return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators.values())]\n+        return _Smoother._smooth2(numerators.values(), denominators.values())\n+\n+    @staticmethod\n+    def _smooth2(\n+        numerators: Union[ValuesView[int], Sequence[int]], denominators: Union[ValuesView[int], Sequence[int]]\n+    ) -> Sequence[float]:\n+        return [(n + 1) / (d + 1) if i != 0 else n / d for i, (n, d) in enumerate(zip(numerators, denominators))]\n \n     @staticmethod\n     def no_smooth(numerators: Counter, denominators: Counter) -> Sequence[float]:\n", "issue": "CI tests are failing on BLEU\nCI tests on Master are failing on checking Bleu metric: \r\n\r\n- https://app.circleci.com/pipelines/github/pytorch/ignite/1755/workflows/00c8cfad-8243-4f5f-9e9e-b8eaeee58b17\r\n- https://github.com/pytorch/ignite/actions/runs/725753501\r\n\r\ncc @sdesrozis @gucifer \n", "before_files": [{"content": "import math\nfrom collections import Counter\nfrom typing import Any, Callable, Sequence, Tuple, Union\n\nimport torch\n\nfrom ignite.exceptions import NotComputableError\nfrom ignite.metrics.metric import Metric, reinit__is_reduced, sync_all_reduce\nfrom ignite.metrics.nlp.utils import modified_precision\n\n__all__ = [\"Bleu\"]\n\n\ndef _closest_ref_length(references: Sequence[Sequence[Any]], hyp_len: int) -> int:\n    ref_lens = (len(reference) for reference in references)\n    closest_ref_len = min(ref_lens, key=lambda ref_len: (abs(ref_len - hyp_len), ref_len))\n    return closest_ref_len\n\n\nclass _Smoother:\n    \"\"\"\n    Smoothing helper\n    http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf\n    \"\"\"\n\n    def __init__(self, method: str):\n        valid = [\"no_smooth\", \"smooth1\", \"nltk_smooth2\", \"smooth2\"]\n        if method not in valid:\n            raise ValueError(f\"Smooth is not valid (expected: {valid}, got: {method})\")\n        self.smooth = method\n\n    def __call__(self, numerators: Counter, denominators: Counter) -> Sequence[float]:\n        method = getattr(self, self.smooth)\n        return method(numerators, denominators)\n\n    @staticmethod\n    def smooth1(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        epsilon = 0.1\n        denominators_ = [max(1, d) for d in denominators.values()]\n        return [n / d if n != 0 else epsilon / d for n, d in zip(numerators.values(), denominators_)]\n\n    @staticmethod\n    def nltk_smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        denominators_ = [max(1, d) for d in denominators.values()]\n        return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators_)]\n\n    @staticmethod\n    def smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        return [(n + 1) / (d + 1) for n, d in zip(numerators.values(), denominators.values())]\n\n    @staticmethod\n    def no_smooth(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        denominators_ = [max(1, d) for d in denominators.values()]\n        return [n / d for n, d in zip(numerators.values(), denominators_)]\n\n\nclass Bleu(Metric):\n    r\"\"\"Calculates the `BLEU score <https://en.wikipedia.org/wiki/BLEU>`_.\n\n    .. math::\n       \\text{BLEU} = b_{p} \\cdot \\exp \\left( \\sum_{n=1}^{N} w_{n} \\: \\log p_{n} \\right)\n\n    where :math:`N` is the order of n-grams, :math:`b_{p}` is a sentence brevety penalty, :math:`w_{n}` are\n    positive weights summing to one and :math:`p_{n}` are modified n-gram precisions.\n\n    More details can be found in `Papineni et al. 2002`__.\n\n    __ https://www.aclweb.org/anthology/P02-1040.pdf\n\n    In addition, a review of smoothing techniques can be found in `Chen et al. 2014`__\n\n    __ http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf\n\n    Remark :\n\n        This implementation is inspired by nltk\n\n    Args:\n        ngram: order of n-grams.\n        smooth: enable smoothing. Valid are ``no_smooth``, ``smooth1``, ``nltk_smooth2`` or ``smooth2``.\n            Default: ``no_smooth``.\n        output_transform: a callable that is used to transform the\n            :class:`~ignite.engine.engine.Engine`'s ``process_function``'s output into the\n            form expected by the metric. This can be useful if, for example, you have a multi-output model and\n            you want to compute the metric with respect to one of the outputs.\n            By default, metrics require the output as ``(y_pred, y)`` or ``{'y_pred': y_pred, 'y': y}``.\n        device: specifies which device updates are accumulated on. Setting the\n            metric's device to be the same as your ``update`` arguments ensures the ``update`` method is\n            non-blocking. By default, CPU.\n\n    Example:\n\n    .. code-block:: python\n\n        from ignite.metrics.nlp import Bleu\n\n        m = Bleu(ngram=4, smooth=\"smooth1\")\n\n        y_pred = \"the the the the the the the\"\n        y = [\"the cat is on the mat\", \"there is a cat on the mat\"]\n\n        m.update((y_pred.split(), [y.split()]))\n\n        print(m.compute())\n\n    .. versionadded:: 0.5.0\n    \"\"\"\n\n    def __init__(\n        self,\n        ngram: int = 4,\n        smooth: str = \"no_smooth\",\n        output_transform: Callable = lambda x: x,\n        device: Union[str, torch.device] = torch.device(\"cpu\"),\n    ):\n        if ngram <= 0:\n            raise ValueError(f\"ngram order must be greater than zero (got: {ngram})\")\n        self.ngrams_order = ngram\n        self.weights = [1 / self.ngrams_order] * self.ngrams_order\n        self.smoother = _Smoother(method=smooth)\n        super(Bleu, self).__init__(output_transform=output_transform, device=device)\n\n    def _corpus_bleu(self, references: Sequence[Sequence[Any]], candidates: Sequence[Sequence[Any]],) -> float:\n        p_numerators: Counter = Counter()\n        p_denominators: Counter = Counter()\n\n        if len(references) != len(candidates):\n            raise ValueError(\n                f\"nb of candidates should be equal to nb of reference lists ({len(candidates)} != \"\n                f\"{len(references)})\"\n            )\n\n        # Iterate through each hypothesis and their corresponding references.\n        for refs, hyp in zip(references, candidates):\n            # For each order of ngram, calculate the numerator and\n            # denominator for the corpus-level modified precision.\n            for i in range(1, self.ngrams_order + 1):\n                numerator, denominator = modified_precision(refs, hyp, i)\n                p_numerators[i] += numerator\n                p_denominators[i] += denominator\n\n        # Returns 0 if there's no matching n-grams\n        # We only need to check for p_numerators[1] == 0, since if there's\n        # no unigrams, there won't be any higher order ngrams.\n        if p_numerators[1] == 0:\n            return 0\n\n        # If no smoother, returns 0 if there's at least one a not matching n-grams\n        if self.smoother.smooth == \"no_smooth\" and min(p_numerators.values()) == 0:\n            return 0\n\n        # Calculate the hypothesis lengths\n        hyp_lengths = [len(hyp) for hyp in candidates]\n\n        # Calculate the closest reference lengths.\n        ref_lengths = [_closest_ref_length(refs, hyp_len) for refs, hyp_len in zip(references, hyp_lengths)]\n\n        # Sum of hypothesis and references lengths\n        hyp_len = sum(hyp_lengths)\n        ref_len = sum(ref_lengths)\n\n        # Calculate corpus-level brevity penalty.\n        if hyp_len < ref_len:\n            bp = math.exp(1 - ref_len / hyp_len) if hyp_len > 0 else 0.0\n        else:\n            bp = 1.0\n\n        # Smoothing\n        p_n = self.smoother(p_numerators, p_denominators)\n\n        # Compute the geometric mean\n        s = [w_i * math.log(p_i) for w_i, p_i in zip(self.weights, p_n)]\n        gm = bp * math.exp(math.fsum(s))\n        return gm\n\n    @reinit__is_reduced\n    def reset(self) -> None:\n        self._sum_of_bleu = torch.tensor(0.0, dtype=torch.double, device=self._device)\n        self._num_sentences = 0\n\n    @reinit__is_reduced\n    def update(self, output: Tuple[Sequence[Any], Sequence[Sequence[Any]]]) -> None:\n        y_pred, y = output\n        self._sum_of_bleu += self._corpus_bleu(references=[y], candidates=[y_pred])\n        self._num_sentences += 1\n\n    @sync_all_reduce(\"_sum_of_bleu\", \"_num_sentences\")\n    def compute(self) -> torch.Tensor:\n        if self._num_sentences == 0:\n            raise NotComputableError(\"Bleu must have at least one example before it can be computed.\")\n        return self._sum_of_bleu / self._num_sentences\n", "path": "ignite/metrics/nlp/bleu.py"}], "after_files": [{"content": "import math\nfrom collections import Counter\nfrom typing import Any, Callable, Sequence, Tuple, Union, ValuesView\n\nimport torch\n\nfrom ignite.exceptions import NotComputableError\nfrom ignite.metrics.metric import Metric, reinit__is_reduced, sync_all_reduce\nfrom ignite.metrics.nlp.utils import modified_precision\n\n__all__ = [\"Bleu\"]\n\n\ndef _closest_ref_length(references: Sequence[Sequence[Any]], hyp_len: int) -> int:\n    ref_lens = (len(reference) for reference in references)\n    closest_ref_len = min(ref_lens, key=lambda ref_len: (abs(ref_len - hyp_len), ref_len))\n    return closest_ref_len\n\n\nclass _Smoother:\n    \"\"\"\n    Smoothing helper\n    http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf\n    \"\"\"\n\n    def __init__(self, method: str):\n        valid = [\"no_smooth\", \"smooth1\", \"nltk_smooth2\", \"smooth2\"]\n        if method not in valid:\n            raise ValueError(f\"Smooth is not valid (expected: {valid}, got: {method})\")\n        self.smooth = method\n\n    def __call__(self, numerators: Counter, denominators: Counter) -> Sequence[float]:\n        method = getattr(self, self.smooth)\n        return method(numerators, denominators)\n\n    @staticmethod\n    def smooth1(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        epsilon = 0.1\n        denominators_ = [max(1, d) for d in denominators.values()]\n        return [n / d if n != 0 else epsilon / d for n, d in zip(numerators.values(), denominators_)]\n\n    @staticmethod\n    def nltk_smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        denominators_ = [max(1, d) for d in denominators.values()]\n        return _Smoother._smooth2(numerators.values(), denominators_)\n\n    @staticmethod\n    def smooth2(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        return _Smoother._smooth2(numerators.values(), denominators.values())\n\n    @staticmethod\n    def _smooth2(\n        numerators: Union[ValuesView[int], Sequence[int]], denominators: Union[ValuesView[int], Sequence[int]]\n    ) -> Sequence[float]:\n        return [(n + 1) / (d + 1) if i != 0 else n / d for i, (n, d) in enumerate(zip(numerators, denominators))]\n\n    @staticmethod\n    def no_smooth(numerators: Counter, denominators: Counter) -> Sequence[float]:\n        denominators_ = [max(1, d) for d in denominators.values()]\n        return [n / d for n, d in zip(numerators.values(), denominators_)]\n\n\nclass Bleu(Metric):\n    r\"\"\"Calculates the `BLEU score <https://en.wikipedia.org/wiki/BLEU>`_.\n\n    .. math::\n       \\text{BLEU} = b_{p} \\cdot \\exp \\left( \\sum_{n=1}^{N} w_{n} \\: \\log p_{n} \\right)\n\n    where :math:`N` is the order of n-grams, :math:`b_{p}` is a sentence brevety penalty, :math:`w_{n}` are\n    positive weights summing to one and :math:`p_{n}` are modified n-gram precisions.\n\n    More details can be found in `Papineni et al. 2002`__.\n\n    __ https://www.aclweb.org/anthology/P02-1040.pdf\n\n    In addition, a review of smoothing techniques can be found in `Chen et al. 2014`__\n\n    __ http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf\n\n    Remark :\n\n        This implementation is inspired by nltk\n\n    Args:\n        ngram: order of n-grams.\n        smooth: enable smoothing. Valid are ``no_smooth``, ``smooth1``, ``nltk_smooth2`` or ``smooth2``.\n            Default: ``no_smooth``.\n        output_transform: a callable that is used to transform the\n            :class:`~ignite.engine.engine.Engine`'s ``process_function``'s output into the\n            form expected by the metric. This can be useful if, for example, you have a multi-output model and\n            you want to compute the metric with respect to one of the outputs.\n            By default, metrics require the output as ``(y_pred, y)`` or ``{'y_pred': y_pred, 'y': y}``.\n        device: specifies which device updates are accumulated on. Setting the\n            metric's device to be the same as your ``update`` arguments ensures the ``update`` method is\n            non-blocking. By default, CPU.\n\n    Example:\n\n    .. code-block:: python\n\n        from ignite.metrics.nlp import Bleu\n\n        m = Bleu(ngram=4, smooth=\"smooth1\")\n\n        y_pred = \"the the the the the the the\"\n        y = [\"the cat is on the mat\", \"there is a cat on the mat\"]\n\n        m.update((y_pred.split(), [y.split()]))\n\n        print(m.compute())\n\n    .. versionadded:: 0.5.0\n    \"\"\"\n\n    def __init__(\n        self,\n        ngram: int = 4,\n        smooth: str = \"no_smooth\",\n        output_transform: Callable = lambda x: x,\n        device: Union[str, torch.device] = torch.device(\"cpu\"),\n    ):\n        if ngram <= 0:\n            raise ValueError(f\"ngram order must be greater than zero (got: {ngram})\")\n        self.ngrams_order = ngram\n        self.weights = [1 / self.ngrams_order] * self.ngrams_order\n        self.smoother = _Smoother(method=smooth)\n        super(Bleu, self).__init__(output_transform=output_transform, device=device)\n\n    def _corpus_bleu(self, references: Sequence[Sequence[Any]], candidates: Sequence[Sequence[Any]],) -> float:\n        p_numerators: Counter = Counter()\n        p_denominators: Counter = Counter()\n\n        if len(references) != len(candidates):\n            raise ValueError(\n                f\"nb of candidates should be equal to nb of reference lists ({len(candidates)} != \"\n                f\"{len(references)})\"\n            )\n\n        # Iterate through each hypothesis and their corresponding references.\n        for refs, hyp in zip(references, candidates):\n            # For each order of ngram, calculate the numerator and\n            # denominator for the corpus-level modified precision.\n            for i in range(1, self.ngrams_order + 1):\n                numerator, denominator = modified_precision(refs, hyp, i)\n                p_numerators[i] += numerator\n                p_denominators[i] += denominator\n\n        # Returns 0 if there's no matching n-grams\n        # We only need to check for p_numerators[1] == 0, since if there's\n        # no unigrams, there won't be any higher order ngrams.\n        if p_numerators[1] == 0:\n            return 0\n\n        # If no smoother, returns 0 if there's at least one a not matching n-grams\n        if self.smoother.smooth == \"no_smooth\" and min(p_numerators.values()) == 0:\n            return 0\n\n        # Calculate the hypothesis lengths\n        hyp_lengths = [len(hyp) for hyp in candidates]\n\n        # Calculate the closest reference lengths.\n        ref_lengths = [_closest_ref_length(refs, hyp_len) for refs, hyp_len in zip(references, hyp_lengths)]\n\n        # Sum of hypothesis and references lengths\n        hyp_len = sum(hyp_lengths)\n        ref_len = sum(ref_lengths)\n\n        # Calculate corpus-level brevity penalty.\n        if hyp_len < ref_len:\n            bp = math.exp(1 - ref_len / hyp_len) if hyp_len > 0 else 0.0\n        else:\n            bp = 1.0\n\n        # Smoothing\n        p_n = self.smoother(p_numerators, p_denominators)\n\n        # Compute the geometric mean\n        s = [w_i * math.log(p_i) for w_i, p_i in zip(self.weights, p_n)]\n        gm = bp * math.exp(math.fsum(s))\n        return gm\n\n    @reinit__is_reduced\n    def reset(self) -> None:\n        self._sum_of_bleu = torch.tensor(0.0, dtype=torch.double, device=self._device)\n        self._num_sentences = 0\n\n    @reinit__is_reduced\n    def update(self, output: Tuple[Sequence[Any], Sequence[Sequence[Any]]]) -> None:\n        y_pred, y = output\n        self._sum_of_bleu += self._corpus_bleu(references=[y], candidates=[y_pred])\n        self._num_sentences += 1\n\n    @sync_all_reduce(\"_sum_of_bleu\", \"_num_sentences\")\n    def compute(self) -> torch.Tensor:\n        if self._num_sentences == 0:\n            raise NotComputableError(\"Bleu must have at least one example before it can be computed.\")\n        return self._sum_of_bleu / self._num_sentences\n", "path": "ignite/metrics/nlp/bleu.py"}]}