# Ce să faci când primești o eroare[[ce-sa-fac-cand-primesti-o-eroare]]

<CourseFloatingBanner chapter={8}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/en/chapter8/section2.ipynb"},
    {label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/en/chapter8/section2.ipynb"},
]} />

În această secțiune vom examina câteva erori comune care pot apărea când încercați să generați predicții din modelul Transformer pe care l-ați ajustat recent. Aceasta vă va pregăti pentru [secțiunea 4](/course/chapter8/section4), unde vom explora cum să depanați faza de antrenament în sine.

<Youtube id="DQ-CpJn6Rc4"/>

Am pregătit un [repository model șablon](https://huggingface.co/lewtun/distilbert-base-uncased-finetuned-squad-d5716d28) pentru această secțiune, și dacă doriți să rulați codul din acest capitol trebuie mai întâi să copiați modelul în contul dumneavoastră pe [Hugging Face Hub](https://huggingface.co). Pentru a face acest lucru, mai întâi conectați-vă rulând fie următoarele într-un notebook Jupyter:

```python
from huggingface_hub import notebook_login

notebook_login()
```

sau următoarele în terminalul dumneavoastră preferat:

```bash
huggingface-cli login
```

Aceasta vă va solicita să introduceți numele de utilizator și parola și va salva un token sub *~/.cache/huggingface/*. Odată ce v-ați conectat, puteți copia repository-ul șablon cu următoarea funcție:

```python
from distutils.dir_util import copy_tree
from huggingface_hub import Repository, snapshot_download, create_repo, get_full_repo_name


def copy_repository_template():
    # Clone the repo and extract the local path
    template_repo_id = "lewtun/distilbert-base-uncased-finetuned-squad-d5716d28"
    commit_hash = "be3eaffc28669d7932492681cd5f3e8905e358b4"
    template_repo_dir = snapshot_download(template_repo_id, revision=commit_hash)
    # Create an empty repo on the Hub
    model_name = template_repo_id.split("/")[1]
    create_repo(model_name, exist_ok=True)
    # Clone the empty repo
    new_repo_id = get_full_repo_name(model_name)
    new_repo_dir = model_name
    repo = Repository(local_dir=new_repo_dir, clone_from=new_repo_id)
    # Copy files
    copy_tree(template_repo_dir, new_repo_dir)
    # Push to Hub
    repo.push_to_hub()
```

Acum când apelați `copy_repository_template()`, aceasta va crea o copie a repository-ului șablon sub contul dumneavoastră.

## Depanarea pipeline-ului din 🤗 Transformers[[depanarea-pipeline-ului-din-transformers]]

Pentru a începe călătoria noastră în lumea minunată a depanării modelelor Transformer, considerați următorul scenariu: lucrați cu un coleg la un proiect de răspuns la întrebări pentru a ajuta clienții unui site web de e-commerce să găsească răspunsuri despre produsele de consum. Colegul dumneavoastră vă trimite un mesaj precum:

> Salut! Tocmai am rulat un experiment folosind tehnicile din [Capitolul 7](/course/chapter7/7) al cursului Hugging Face și am obținut rezultate grozave pe SQuAD! Cred că putem folosi acest model ca punct de plecare pentru proiectul nostru. ID-ul modelului pe Hub este "lewtun/distillbert-base-uncased-finetuned-squad-d5716d28". Simte-te liber să îl testezi :)

Iar primul lucru la care vă gândiți este să încărcați modelul folosind `pipeline` din 🤗 Transformers:

```python
from transformers import pipeline

model_checkpoint = get_full_repo_name("distillbert-base-uncased-finetuned-squad-d5716d28")
reader = pipeline("question-answering", model=model_checkpoint)
```

```python out
"""
OSError: Can't load config for 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28'. Make sure that:

- 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

Oh nu, se pare că ceva a mers prost! Dacă sunteți nou în programare, acest tip de erori pot părea puțin criptice la început (ce este un `OSError`?!). Eroarea afișată aici este doar ultima parte dintr-un raport de eroare mult mai mare numit _Python traceback_ (cunoscut și ca stack trace). De exemplu, dacă rulați acest cod pe Google Colab, ar trebui să vedeți ceva similar cu următoarea captură de ecran:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/traceback.png" alt="Un traceback Python." width="100%"/>
</div>

Există multe informații conținute în aceste rapoarte, așa că să parcurgem împreună părțile cheie. Primul lucru de reținut este că traceback-urile ar trebui citite _de jos în sus_. Aceasta poate părea ciudat dacă sunteți obișnuiți să citiți textul în engleză de sus în jos, dar reflectă faptul că traceback-ul arată secvența de apeluri de funcții pe care `pipeline` le face când descarcă modelul și tokenizer-ul. (Consultați [Capitolul 2](/course/chapter2) pentru mai multe detalii despre cum funcționează `pipeline` în culise.)

<Tip>

🚨 Vedeți acea casetă albastră din jurul "6 frames" în traceback-ul din Google Colab? Aceasta este o caracteristică specială a Colab, care comprimă traceback-ul în "frame-uri". Dacă nu reușiți să găsiți sursa unei erori, asigurați-vă că extindeți traceback-ul complet făcând clic pe acele două săgeți mici.

</Tip>

Aceasta înseamnă că ultima linie a traceback-ului indică ultimul mesaj de eroare și dă numele excepției care a fost ridicată. În acest caz, tipul excepției este `OSError`, care indică o eroare legată de sistem. Dacă citim mesajul de eroare însoțitor, putem vedea că pare să existe o problemă cu fișierul *config.json* al modelului și ni se dau două sugestii pentru a o rezolva:

```python out
"""
Make sure that:

- 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

<Tip>

💡 Dacă întâlniți un mesaj de eroare care este dificil de înțeles, doar copiați și lipiți mesajul în bara de căutare Google sau [Stack Overflow](https://stackoverflow.com/) (da, chiar!). Există o șansă bună că nu sunteți prima persoană care întâlnește eroarea, și aceasta este o modalitate bună de a găsi soluții pe care alții din comunitate le-au postat. De exemplu, căutarea pentru `OSError: Can't load config for` pe Stack Overflow dă mai multe [rezultate](https://stackoverflow.com/search?q=OSError%3A+Can%27t+load+config+for+) care ar putea fi folosite ca punct de plecare pentru rezolvarea problemei.

</Tip>

Prima sugestie ne cere să verificăm dacă ID-ul modelului este într-adevăr corect, așa că primul lucru de făcut este să copiem identificatorul și să îl lipim în bara de căutare a Hub-ului:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/wrong-model-id.png" alt="Numele greșit al modelului." width="100%"/>
</div>

Hmm, într-adevăr pare că modelul colegului nostru nu este pe Hub... aha, dar există o greșeală de tipar în numele modelului! DistilBERT are doar un "l" în numele său, așa că să corectăm asta și să căutăm "lewtun/distilbert-base-uncased-finetuned-squad-d5716d28" în schimb:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/true-model-id.png" alt="Numele corect al modelului." width="100%"/>
</div>

Bun, aceasta a dat un rezultat. Acum să încercăm să descărcăm din nou modelul cu ID-ul corect:

```python
model_checkpoint = get_full_repo_name("distilbert-base-uncased-finetuned-squad-d5716d28")
reader = pipeline("question-answering", model=model_checkpoint)
```

```python out
"""
OSError: Can't load config for 'lewtun/distilbert-base-uncased-finetuned-squad-d5716d28'. Make sure that:

- 'lewtun/distilbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distilbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

Argh, eșuat din nou -- bun venit în viața de zi cu zi a unui inginer de machine learning! Deoarece am corectat ID-ul modelului, problema trebuie să fie în repository în sine. O modalitate rapidă de a accesa conținutul unui repository pe 🤗 Hub este prin funcția `list_repo_files()` din biblioteca `huggingface_hub`:

```python
from huggingface_hub import list_repo_files

list_repo_files(repo_id=model_checkpoint)
```

```python out
['.gitattributes', 'README.md', 'pytorch_model.bin', 'special_tokens_map.json', 'tokenizer_config.json', 'training_args.bin', 'vocab.txt']
```

Interesant -- nu pare să existe un fișier *config.json* în repository! Nu e de mirare că `pipeline`-ul nostru nu a putut încărca modelul; colegul nostru trebuie să fi uitat să împingă acest fișier pe Hub după ce l-a ajustat fin. În acest caz, problema pare destul de simplă de rezolvat: am putea să îi cerem să adauge fișierul, sau, deoarece putem vedea din ID-ul modelului că modelul preantrenat folosit a fost [`distilbert-base-uncased`](https://huggingface.co/distilbert-base-uncased), putem descărca configurația pentru acest model și să o împingem în repository-ul nostru pentru a vedea dacă aceasta rezolvă problema. Să încercăm asta. Folosind tehnicile pe care le-am învățat în [Capitolul 2](/course/chapter2), putem descărca configurația modelului cu clasa `AutoConfig`:

```python
from transformers import AutoConfig

pretrained_checkpoint = "distilbert-base-uncased"
config = AutoConfig.from_pretrained(pretrained_checkpoint)
```

<Tip warning={true}>

🚨 Abordarea pe care o adoptăm aici nu este infailibilă, deoarece colegul nostru poate să fi modificat configurația `distilbert-base-uncased` înainte de a ajusta fin modelul. În viața reală, am vrea să verificăm cu ei mai întâi, dar în scopurile acestei secțiuni vom presupune că au folosit configurația implicită.

</Tip>

Apoi putem împinge aceasta în repository-ul nostru de model cu funcția `push_to_hub()` a configurației:

```python
config.push_to_hub(model_checkpoint, commit_message="Add config.json")
```

Acum putem testa dacă aceasta a funcționat încărcând modelul din cel mai recent commit pe ramura `main`:

```python
reader = pipeline("question-answering", model=model_checkpoint, revision="main")

context = r"""
Extractive Question Answering is the task of extracting an answer from a text
given a question. An example of a question answering dataset is the SQuAD
dataset, which is entirely based on that task. If you would like to fine-tune a
model on a SQuAD task, you may leverage the
examples/pytorch/question-answering/run_squad.py script.

🤗 Transformers is interoperable with the PyTorch, TensorFlow, and JAX
frameworks, so you can use your favourite tools for a wide variety of tasks!
"""

question = "What is extractive question answering?"
reader(question=question, context=context)
```

```python out
{'score': 0.38669535517692566,
 'start': 34,
 'end': 95,
 'answer': 'the task of extracting an answer from a text given a question'}
```

Woohoo, a funcționat! Să recapitulăm ce ați învățat tocmai:

- Mesajele de eroare în Python sunt cunoscute ca _traceback-uri_ și sunt citite de jos în sus. Ultima linie a mesajului de eroare conține de obicei informațiile de care aveți nevoie pentru a localiza sursa problemei.
- Dacă ultima linie nu conține informații suficiente, parcurgeți traceback-ul în sus și vedeți dacă puteți identifica unde în codul sursă apare eroarea.
- Dacă niciunul dintre mesajele de eroare nu vă poate ajuta să depanați problema, încercați să căutați online o soluție la o problemă similară.
- Biblioteca `huggingface_hub` oferă o suită de instrumente pe care le puteți folosi pentru a interacționa cu și a depana repository-urile de pe Hub.

Acum că știți cum să depanați un pipeline, să aruncăm o privire la un exemplu mai complicat în forward pass-ul modelului în sine.

## Depanarea forward pass-ului modelului dumneavoastră[[depanarea-forward-pass-ului-modelului-dumneavoastra]]

Deși `pipeline` este grozav pentru majoritatea aplicațiilor unde aveți nevoie să generați rapid predicții, uneori va trebui să accesați logit-urile modelului (să zicem, dacă aveți o post-procesare personalizată pe care ați dori să o aplicați). Pentru a vedea ce poate merge prost în acest caz, să extragem mai întâi modelul și tokenizer-ul din `pipeline`-ul nostru:

```python
tokenizer = reader.tokenizer
model = reader.model
```

Apoi avem nevoie de o întrebare, așa că să vedem dacă framework-urile noastre preferate sunt suportate:

```python
question = "Which frameworks can I use?"
```

Așa cum am văzut în [Capitolul 7](/course/chapter7), pașii obișnuiți pe care trebuie să îi facem sunt tokenizarea intrărilor, extragerea logit-urilor token-urilor de început și sfârșit, și apoi decodarea span-ului de răspuns:

```python
import torch

inputs = tokenizer(question, context, add_special_tokens=True)
input_ids = inputs["input_ids"][0]
outputs = model(**inputs)
answer_start_scores = outputs.start_logits
answer_end_scores = outputs.end_logits
# Get the most likely beginning of answer with the argmax of the score
answer_start = torch.argmax(answer_start_scores)
# Get the most likely end of answer with the argmax of the score
answer_end = torch.argmax(answer_end_scores) + 1
answer = tokenizer.convert_tokens_to_string(
    tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end])
)
print(f"Question: {question}")
print(f"Answer: {answer}")
```

```python out
"""
OSError: Can't load config for 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28'. Make sure that:

- 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is a correct model identifier listed on 'https://huggingface.co/models'

- or 'lewtun/distillbert-base-uncased-finetuned-squad-d5716d28' is the correct path to a directory containing a config.json file
"""
```

Oh nu, se pare că avem o eroare în codul nostru! Dar nu ne temem de puțină depanare. Puteți folosi debugger-ul Python într-un notebook:

<Youtube id="rSPyvPw0p9k"/>

sau într-un terminal:

<Youtube id="5PkZ4rbHL6c"/>

Aici, citirea mesajului de eroare ne spune că `'list' object has no attribute 'size'`, și putem vedea o săgeată `-->` care indică linia unde a fost ridicată problema în `model(**inputs)`. Puteți depana aceasta interactiv folosind debugger-ul Python, dar pentru moment vom afișa pur și simplu o porțiune din `inputs` pentru a vedea ce avem:

```python
inputs["input_ids"][:5]
```

```python out
[101, 2029, 7705, 2015, 2064]
```

Aceasta cu siguranță arată ca o `list` Python obișnuită, dar să verificăm din nou tipul:

```python
type(inputs["input_ids"])
```

```python out
list
```

Da, aceasta este cu siguranță o `list` Python. Deci ce a mers prost? Amintiți-vă din [Capitolul 2](/course/chapter2) că clasele `AutoModelForXxx` din 🤗 Transformers operează pe _tensori_ (fie în PyTorch sau TensorFlow), și o operație comună este să extragi dimensiunile unui tensor folosind `Tensor.size()` în, să zicem, PyTorch. Să aruncăm din nou o privire la traceback, pentru a vedea care linie a declanșat excepția:

```
~/miniconda3/envs/huggingface/lib/python3.8/site-packages/transformers/models/distilbert/modeling_distilbert.py in forward(self, input_ids, attention_mask, head_mask, inputs_embeds, output_attentions, output_hidden_states, return_dict)
    471             raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
    472         elif input_ids is not None:
--> 473             input_shape = input_ids.size()
    474         elif inputs_embeds is not None:
    475             input_shape = inputs_embeds.size()[:-1]

AttributeError: 'list' object has no attribute 'size'
```

Se pare că codul nostru a încercat să apeleze `input_ids.size()`, dar aceasta în mod clar nu va funcționa pentru o `list` Python, care este doar un container. Cum putem rezolva această problemă? Căutarea mesajului de eroare pe Stack Overflow oferă destul de multe [rezultate](https://stackoverflow.com/search?q=AttributeError%3A+%27list%27+object+has+no+attribute+%27size%27&s=c15ec54c-63cb-481d-a749-408920073e8f) relevante. Făcând clic pe primul afișează o întrebare similară cu a noastră, cu răspunsul arătat în captura de ecran de mai jos:

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter8/stack-overflow.png" alt="Un răspuns de pe Stack Overflow." width="100%"/>
</div>

Răspunsul recomandă să adăugăm `return_tensors='pt'` la tokenizer, așa că să vedem dacă aceasta funcționează pentru noi:

```python out
inputs = tokenizer(question, context, add_special_tokens=True, return_tensors="pt")
input_ids = inputs["input_ids"][0]
outputs = model(**inputs)
answer_start_scores = outputs.start_logits
answer_end_scores = outputs.end_logits
# Get the most likely beginning of answer with the argmax of the score
answer_start = torch.argmax(answer_start_scores)
# Get the most likely end of answer with the argmax of the score
answer_end = torch.argmax(answer_end_scores) + 1
answer = tokenizer.convert_tokens_to_string(
    tokenizer.convert_ids_to_tokens(input_ids[answer_start:answer_end])
)
print(f"Question: {question}")
print(f"Answer: {answer}")
```

```python out
"""
Question: Which frameworks can I use?
Answer: pytorch, tensorflow, and jax
"""
```

Minunat, a funcționat! Acesta este un exemplu grozav de cât de util poate fi Stack Overflow: prin identificarea unei probleme similare, am putut beneficia de experiența altora din comunitate. Cu toate acestea, o căutare ca aceasta nu va da întotdeauna un răspuns relevant, așa că ce puteți face în astfel de cazuri? Din fericire, există o comunitate primitoare de dezvoltatori pe [forumurile Hugging Face](https://discuss.huggingface.co/) care vă pot ajuta! În secțiunea următoare, vom arunca o privire asupra modului în care puteți formula întrebări bune pe forum care au șanse să primească răspuns. 

<EditOnGithub source="https://github.com/huggingface/course/blob/main/chapters/ro/chapter8/2.mdx" />