prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  HuggingFace model should update word embeddings dimension according to tokenizer
  ** To reproduce
  
  Steps to reproduce the behavior:
  
  Right now if I call 
  
  ```
  model = transformers.AutoModelForCausalLM.from_pretrained('bigscience/bloom-560m')
  tokenizer = transformers.AutoTokenizer.from_pretrained('gpt2')
  
  model = HuggingFaceModel(model=model, tokenizer=tokenizer)
  ```
  
  The bloom model will have a [250880, 1024] dim word embedding matrix and a vocab size of 250880 even though a gpt2 tokenizer with vocab size of 50257 is used.
  
  ## Expected behavior
  
  The class HuggingFaceModel needs to update word embedding matrix if a tokenizer is supplied.
  
  
  
  </issue>
  <code>
  [start of composer/models/huggingface.py]
  1 # Copyright 2022 MosaicML Composer authors
  2 # SPDX-License-Identifier: Apache-2.0
  3 
  4 """A wrapper class that converts 🤗 Transformers models to composer models"""
  5 
  6 from __future__ import annotations
  7 
  8 from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
  9 
  10 from torchmetrics import Metric
  11 
  12 from composer.models.base import ComposerModel
  13 from composer.utils.import_helpers import MissingConditionalImportError
  14 
  15 if TYPE_CHECKING:
  16     import transformers
  17 
  18 __all__ = ['HuggingFaceModel']
  19 
  20 
  21 class HuggingFaceModel(ComposerModel):
  22     """
  23     A wrapper class that converts 🤗 Transformers models to composer models.
  24 
  25     Args:
  26         model (transformers.PreTrainedModel): A 🤗 Transformers model.
  27         tokenizer (transformers.PreTrainedTokenizer): Tokenizer used to prepare the dataset and validate model inputs during training. Default ``None``.
  28         use_logits (bool, optional): If True, the model's output logits will be used to calculate validation metrics. Else, metrics will be inferred from the HuggingFaceModel directly. Default: ``False``
  29         metrics (list[Metric], optional): list of torchmetrics to apply to the output of `validate`. Default: ``None``.
  30     .. warning:: This wrapper is designed to work with 🤗 datasets that define a `labels` column.
  31 
  32     Example:
  33 
  34     .. testcode::
  35 
  36         import transformers
  37         from composer.models import HuggingFaceModel
  38 
  39         hf_model = transformers.AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
  40         model = HuggingFaceModel(hf_model)
  41     """
  42 
  43     def __init__(self,
  44                  model: transformers.PreTrainedModel,
  45                  tokenizer: Optional[Union[transformers.PreTrainedTokenizer,
  46                                            transformers.PreTrainedTokenizerFast]] = None,
  47                  use_logits: Optional[bool] = False,
  48                  metrics: Optional[List[Metric]] = None) -> None:
  49         try:
  50             import transformers
  51         except ImportError as e:
  52             raise MissingConditionalImportError(extra_deps_group='nlp', conda_package='transformers') from e
  53 
  54         super().__init__()
  55         self.model = model
  56         self.config = model.config
  57 
  58         # the set of inputs that a model expects inferred from the model type or
  59         # tokenizer if provided
  60         if tokenizer is None:
  61             if isinstance(self.model.base_model, transformers.GPT2Model):
  62                 self.model_inputs = {'input_ids', 'attention_mask'}
  63             elif isinstance(self.model.base_model, transformers.BertModel):
  64                 self.model_inputs = {'input_ids', 'attention_mask', 'token_type_ids'}
  65         else:
  66             assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'
  67             self.model_inputs = set(tokenizer.model_input_names)
  68 
  69         self.use_logits = use_logits
  70 
  71         self.train_metrics = None
  72         self.val_metrics = None
  73 
  74         if metrics:
  75             self.train_metrics = {metric.__class__.__name__: metric for metric in metrics}
  76             self.val_metrics = {metric.__class__.__name__: metric for metric in metrics}
  77 
  78         self.labels = None  # set in eval_forward() if exists
  79 
  80     def forward(self, batch):
  81         for key in self.model_inputs:
  82             if key not in batch.keys():
  83                 raise ValueError(f'Batch missing key: {key}')
  84 
  85         output = self.model(**batch)  # type: ignore (thirdparty)
  86         return output
  87 
  88     def loss(self, outputs, batch):
  89         return outputs['loss']
  90 
  91     def eval_forward(self, batch, outputs: Optional[Any] = None):
  92         output = outputs if outputs else self.forward(batch)
  93         if self.use_logits:
  94             self.labels = batch.pop('labels')
  95             output = output['logits']
  96 
  97             # if we are in the single class case, then remove the classes dimension
  98             if output.shape[1] == 1:
  99                 output = output.squeeze(dim=1)
  100 
  101         return output
  102 
  103     def get_metrics(self, is_train: bool = False) -> Dict[str, Metric]:
  104         if is_train:
  105             metrics = self.train_metrics
  106         else:
  107             metrics = self.val_metrics
  108 
  109         return metrics if metrics else {}
  110 
  111     def update_metric(self, batch: Any, outputs: Any, metric: Metric) -> None:
  112         metric.update(outputs, self.labels)
  113 
  114     def get_model_inputs(self):
  115         """Returns a set of inputs that the model expects in the forward pass.
  116         If an algorithm wants to interact with the model inputs (for instance,
  117         popping the labels for a custom loss fn, or adding attention head masks
  118         for head pruning, it must access self.set_model_inputs().
  119         Returns:
  120             model_inputs: The set of keys that are expected in the Mapping used to compute the forward pass.
  121         """
  122 
  123         return self.model_inputs
  124
  [end of composer/models/huggingface.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/composer/models/huggingface.py b/composer/models/huggingface.py
  --- a/composer/models/huggingface.py
  +++ b/composer/models/huggingface.py
  @@ -5,6 +5,7 @@
   
   from __future__ import annotations
   
  +import logging
   from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
   
   from torchmetrics import Metric
  @@ -15,6 +16,8 @@
   if TYPE_CHECKING:
       import transformers
   
  +log = logging.getLogger(__name__)
  +
   __all__ = ['HuggingFaceModel']
   
   
  @@ -66,6 +69,13 @@
               assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'
               self.model_inputs = set(tokenizer.model_input_names)
   
  +            if self.config.vocab_size != len(tokenizer):
  +                # set model's word embedding matrix and final lm_head to vocab size according to tokenizer
  +                log.warning(
  +                    f'The number of tokens in the tokenizer and the number of tokens in the model are different.'
  +                    f' Resizing the model tokenizer to {len(tokenizer)} from {self.config.vocab_size}.')
  +                self.model.resize_token_embeddings(len(tokenizer))
  +
           self.use_logits = use_logits
   
           self.train_metrics = None
  
verification_info: {"golden_diff": "diff --git a/composer/models/huggingface.py b/composer/models/huggingface.py\n--- a/composer/models/huggingface.py\n+++ b/composer/models/huggingface.py\n@@ -5,6 +5,7 @@\n \n from __future__ import annotations\n \n+import logging\n from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union\n \n from torchmetrics import Metric\n@@ -15,6 +16,8 @@\n if TYPE_CHECKING:\n     import transformers\n \n+log = logging.getLogger(__name__)\n+\n __all__ = ['HuggingFaceModel']\n \n \n@@ -66,6 +69,13 @@\n             assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'\n             self.model_inputs = set(tokenizer.model_input_names)\n \n+            if self.config.vocab_size != len(tokenizer):\n+                # set model's word embedding matrix and final lm_head to vocab size according to tokenizer\n+                log.warning(\n+                    f'The number of tokens in the tokenizer and the number of tokens in the model are different.'\n+                    f' Resizing the model tokenizer to {len(tokenizer)} from {self.config.vocab_size}.')\n+                self.model.resize_token_embeddings(len(tokenizer))\n+\n         self.use_logits = use_logits\n \n         self.train_metrics = None\n", "issue": "HuggingFace model should update word embeddings dimension according to tokenizer\n** To reproduce\r\n\r\nSteps to reproduce the behavior:\r\n\r\nRight now if I call \r\n\r\n```\r\nmodel = transformers.AutoModelForCausalLM.from_pretrained('bigscience/bloom-560m')\r\ntokenizer = transformers.AutoTokenizer.from_pretrained('gpt2')\r\n\r\nmodel = HuggingFaceModel(model=model, tokenizer=tokenizer)\r\n```\r\n\r\nThe bloom model will have a [250880, 1024] dim word embedding matrix and a vocab size of 250880 even though a gpt2 tokenizer with vocab size of 50257 is used.\r\n\r\n## Expected behavior\r\n\r\nThe class HuggingFaceModel needs to update word embedding matrix if a tokenizer is supplied.\r\n\r\n\n", "before_files": [{"content": "# Copyright 2022 MosaicML Composer authors\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"A wrapper class that converts \ud83e\udd17 Transformers models to composer models\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import TYPE_CHECKING, Any, Dict, List, Optional, Union\n\nfrom torchmetrics import Metric\n\nfrom composer.models.base import ComposerModel\nfrom composer.utils.import_helpers import MissingConditionalImportError\n\nif TYPE_CHECKING:\n    import transformers\n\n__all__ = ['HuggingFaceModel']\n\n\nclass HuggingFaceModel(ComposerModel):\n    \"\"\"\n    A wrapper class that converts \ud83e\udd17 Transformers models to composer models.\n\n    Args:\n        model (transformers.PreTrainedModel): A \ud83e\udd17 Transformers model.\n        tokenizer (transformers.PreTrainedTokenizer): Tokenizer used to prepare the dataset and validate model inputs during training. Default ``None``.\n        use_logits (bool, optional): If True, the model's output logits will be used to calculate validation metrics. Else, metrics will be inferred from the HuggingFaceModel directly. Default: ``False``\n        metrics (list[Metric], optional): list of torchmetrics to apply to the output of `validate`. Default: ``None``.\n    .. warning:: This wrapper is designed to work with \ud83e\udd17 datasets that define a `labels` column.\n\n    Example:\n\n    .. testcode::\n\n        import transformers\n        from composer.models import HuggingFaceModel\n\n        hf_model = transformers.AutoModelForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)\n        model = HuggingFaceModel(hf_model)\n    \"\"\"\n\n    def __init__(self,\n                 model: transformers.PreTrainedModel,\n                 tokenizer: Optional[Union[transformers.PreTrainedTokenizer,\n                                           transformers.PreTrainedTokenizerFast]] = None,\n                 use_logits: Optional[bool] = False,\n                 metrics: Optional[List[Metric]] = None) -> None:\n        try:\n            import transformers\n        except ImportError as e:\n            raise MissingConditionalImportError(extra_deps_group='nlp', conda_package='transformers') from e\n\n        super().__init__()\n        self.model = model\n        self.config = model.config\n\n        # the set of inputs that a model expects inferred from the model type or\n        # tokenizer if provided\n        if tokenizer is None:\n            if isinstance(self.model.base_model, transformers.GPT2Model):\n                self.model_inputs = {'input_ids', 'attention_mask'}\n            elif isinstance(self.model.base_model, transformers.BertModel):\n                self.model_inputs = {'input_ids', 'attention_mask', 'token_type_ids'}\n        else:\n            assert tokenizer.model_input_names is not None, 'the tokenizer should have a model input name'\n            self.model_inputs = set(tokenizer.model_input_names)\n\n        self.use_logits = use_logits\n\n        self.train_metrics = None\n        self.val_metrics = None\n\n        if metrics:\n            self.train_metrics = {metric.__class__.__name__: metric for metric in metrics}\n            self.val_metrics = {metric.__class__.__name__: metric for metric in metrics}\n\n        self.labels = None  # set in eval_forward() if exists\n\n    def forward(self, batch):\n        for key in self.model_inputs:\n            if key not in batch.keys():\n                raise ValueError(f'Batch missing key: {key}')\n\n        output = self.model(**batch)  # type: ignore (thirdparty)\n        return output\n\n    def loss(self, outputs, batch):\n        return outputs['loss']\n\n    def eval_forward(self, batch, outputs: Optional[Any] = None):\n        output = outputs if outputs else self.forward(batch)\n        if self.use_logits:\n            self.labels = batch.pop('labels')\n            output = output['logits']\n\n            # if we are in the single class case, then remove the classes dimension\n            if output.shape[1] == 1:\n                output = output.squeeze(dim=1)\n\n        return output\n\n    def get_metrics(self, is_train: bool = False) -> Dict[str, Metric]:\n        if is_train:\n            metrics = self.train_metrics\n        else:\n            metrics = self.val_metrics\n\n        return metrics if metrics else {}\n\n    def update_metric(self, batch: Any, outputs: Any, metric: Metric) -> None:\n        metric.update(outputs, self.labels)\n\n    def get_model_inputs(self):\n        \"\"\"Returns a set of inputs that the model expects in the forward pass.\n        If an algorithm wants to interact with the model inputs (for instance,\n        popping the labels for a custom loss fn, or adding attention head masks\n        for head pruning, it must access self.set_model_inputs().\n        Returns:\n            model_inputs: The set of keys that are expected in the Mapping used to compute the forward pass.\n        \"\"\"\n\n        return self.model_inputs\n", "path": "composer/models/huggingface.py"}]}