Buckets:
| # 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. | |
| 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. | |
| 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) | |
| ``` | |
| > [!WARNING] | |
| > 🚨 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ă. | |
| 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" /> |
Xet Storage Details
- Size:
- 18.9 kB
- Xet hash:
- b6209159891642f6696da81eaffe0ac92ab5c58fbb58c8277efcecf54c9a5c75
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.