From 6b0cb4865fdb5c6ef2f7a72ef1380a19110691e8 Mon Sep 17 00:00:00 2001 From: "ludmila.friptu" Date: Sat, 28 Sep 2024 20:30:02 +0300 Subject: [PATCH 001/167] Add chapter1 with file1 rom --- chapters/rum/chapter1/1.mdx | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 chapters/rum/chapter1/1.mdx diff --git a/chapters/rum/chapter1/1.mdx b/chapters/rum/chapter1/1.mdx new file mode 100644 index 000000000..e69de29bb From af5d9a5a399a37bb401b3f4a9eec39fa1e7319e1 Mon Sep 17 00:00:00 2001 From: "ludmila.friptu" Date: Sat, 28 Sep 2024 20:35:57 +0300 Subject: [PATCH 002/167] Add file1 with content --- chapters/rum/chapter1/1.mdx | 211 ++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/chapters/rum/chapter1/1.mdx b/chapters/rum/chapter1/1.mdx index e69de29bb..4e00b799a 100644 --- a/chapters/rum/chapter1/1.mdx +++ b/chapters/rum/chapter1/1.mdx @@ -0,0 +1,211 @@ +# Introducere[[introduction]] + + + +## Bun venit la 🤗 curs![[bun-venit-la-curs]] + + +Acest curs vă va învăța despre procesarea limbajelor naturale (NLP) folosind biblioteci din [Hugging Face](https://huggingface.co/) ecosystem — [🤗 Transformers](https://github.com/huggingface/transformers), [🤗 Datasets](https://github.com/huggingface/datasets), [🤗 Tokenizers](https://github.com/huggingface/tokenizers), and [🤗 Accelerate](https://github.com/huggingface/accelerate) — precum și [Hugging Face Hub](https://huggingface.co/models).Este complet gratuit și nu conține reclame. + +## La ce să te aștepți?[[la-ce-sa-te-aștepți]] + +Aceasta este o scurtă prezentare a cursului: + +
+Brief overview of the chapters of the course. + +
+ +- Capitolele 1-4 oferă o introducere în conceptele fundamentale ale bibliotecii 🤗 Transformers. Până la sfârșitul acestei părți a cursului, veți fi familiarizați cu modul în care funcționează modelele Transformer și veți ști cum să utilizați un model din [Hugging Face Hub](https://huggingface.co/models), să îl ajustați pe un set de date și să vă partajați rezultatele pe Hub! +- # Introducere[[introduction]] + + + +## Bun venit la 🤗 curs![[bun-venit-la-curs]] + + +Acest curs vă va învăța despre procesarea limbajelor naturale (NLP) folosind biblioteci din [Hugging Face](https://huggingface.co/) ecosystem — [🤗 Transformers](https://github.com/huggingface/transformers), [🤗 Datasets](https://github.com/huggingface/datasets), [🤗 Tokenizers](https://github.com/huggingface/tokenizers), and [🤗 Accelerate](https://github.com/huggingface/accelerate) — precum și [Hugging Face Hub](https://huggingface.co/models).Este complet gratuit și nu conține reclame. + +## La ce să te aștepți?[[la-ce-sa-te-aștepți]] + +Aceasta este o scurtă prezentare a cursului: + +
+Brief overview of the chapters of the course. + +
+ +- Capitolele 1-4 oferă o introducere în conceptele fundamentale ale bibliotecii 🤗 Transformers. Până la sfârșitul acestei părți a cursului, veți fi familiarizați cu modul în care funcționează modelele Transformer și veți ști cum să utilizați un model din [Hugging Face Hub](https://huggingface.co/models), să îl ajustați pe un set de date și să vă partajați rezultatele pe Hub! +- Capitolele 5-8 predau elementele de bază ale Datasets 🤗 și ale Tokenizerelor 🤗 înainte de a vă scufunda în sarcinile NLP. Până la sfârșitul acestei părți, veți fi capabil să abordați singur cele mai frecvente probleme NLP. +- Capitolele 9-12 trec dincolo de NLP și explorează modul în care modelele Transformer pot fi utilizate pentru a aborda sarcini din domeniul procesării semnalelor vorbirii și al viziunii computerizate. Pe parcurs, veți învăța cum să construiți și să partajați demo-uri ale modelelor dumneavoastră și cum să le optimizați pentru mediul de producție. Până la sfârșitul acestei părți, veți fi gata să aplicați 🤗 Transformers la (aproape) orice problemă de machine learning! + +Acest curs: + +* Necesită o bună cunoaștere a limbajului Python. +* Este mai bine să fie urmat după un curs introductiv de deep learning, cum ar fi [fast.ai's](https://www.fast.ai/) [Practical Deep Learning for Coders](https://course.fast.ai/) sau unul dintre programele dezvoltate de [DeepLearning.AI](https://www.deeplearning.ai/). +* Nu se așteaptă la cunoștințe anterioare despre [PyTorch](https://pytorch.org/) sau [TensorFlow](https://www.tensorflow.org/), deși o familiaritate cu oricare dintre acestea va fi de ajutor. + +După ce ați completat acest curs, vă recomandăm să accesați [Natural Language Processing Specialization] (https://www.coursera.org/specializations/natural-language-processing?utm_source=deeplearning-ai&utm_medium=institutions&utm_campaign=20211011-nlp-2-hugging_face-page-nlp-refresh) de la DeepLearning.AI, care acoperă o gamă largă de modele NLP clasice, cum ar fi naive Bayes și LSTMs, despre care este bine să știți! + +## Cine suntem noi?[[cine-suntem-noi]] + +Despre autori: + +[**Abubakar Abid**](https://huggingface.co/abidlabs) și-a susținut doctoratul la Stanford în domeniul învățării automate (Machine Learning) aplicate. În timpul doctoratului său, a fondat [Gradio](https://github.com/gradio-app/gradio), o bibliotecă Python open-source care a fost utilizată pentru a construi peste 600.000 de demo-uri de Machine Learning. Gradio a fost achiziționată de Hugging Face, unde Abubakar activează acum ca lider al echipei de Machine Learning. + +[**Matthew Carrigan**](https://huggingface.co/Rocketknight1) este inginer de Machine Learning la Hugging Face. Locuiește în Dublin, Irlanda și a lucrat anterior ca inginer ML la Parse.ly și înainte de asta ca cercetător postdoctoral la Trinity College Dublin. El nu crede că vom ajunge la AGI prin scalarea arhitecturilor existente, dar are mari speranțe în ceea ce privește nemurirea roboților. + +[**Lysandre Debut**](https://huggingface.co/lysandre) este inginer de Machine Learning la Hugging Face și a lucrat la biblioteca 🤗 Transformers încă din primele etape de dezvoltare. Scopul său este de a face NLP accesibil pentru toată lumea prin dezvoltarea de instrumente cu un API foarte simplu. + +[**Sylvain Gugger**](https://huggingface.co/sgugger) este inginer de cercetare în Machine Learning la Hugging Face și unul dintre principalii întreținători ai bibliotecii 🤗 Transformers. Anterior a fost cercetător științific la fast.ai și a fost coautor la _[Deep Learning for Coders with fastai and PyTorch](https://learning.oreilly.com/library/view/deep-learning-for/9781492045519/)_ cu Jeremy Howard. Obiectivul principal al cercetării sale este de a face învățarea profundă mai accesibilă, prin proiectarea și îmbunătățirea tehnicilor care permit modelelor să se antreneze rapid pe resurse limitate. + +[**Dawood Khan**](https://huggingface.co/dawoodkhan82) este inginer de Machine Learning la Hugging Face. Este originar din New York și a absolvit Universitatea din New York, unde a studiat Informatica. După ce a lucrat ca inginer iOS timp de câțiva ani, Dawood a demisionat pentru a înființa Gradio împreună cu colegii săi co-fondatori. Gradio a fost în cele din urmă achiziționat de Hugging Face. + +[**Merve Noyan**](https://huggingface.co/merve) este un susținător al dezvoltatorilor la Hugging Face, lucrând la dezvoltarea de instrumente și la crearea de conținut în jurul acestora pentru a facilita învățarea automată pentru toată lumea. + +[**Lucile Saulnier**](https://huggingface.co/SaulLu) este inginer de Machine Learning la Hugging Face, dezvoltând și susținând utilizarea de instrumente open source. De asemenea, este implicată activ în multe proiecte de cercetare în domeniul procesării limbajului natural, cum ar fi formarea colaborativă și BigScience. + +[**Lewis Tunstall**](https://huggingface.co/lewtun) este inginer de Machine Learning la Hugging Face, concentrându-se pe dezvoltarea de instrumente open-source și pe asigurarea accesibilității acestora pentru întreaga comunitate. De asemenea, este coautor al cărții O'Reilly [Natural Language Processing with Transformers] (https://www.oreilly.com/library/view/natural-language-processing/9781098136789/). + +[**Leandro von Werra**](https://huggingface.co/lvwerra) este inginer de Machine Learning în cadrul echipei open-source de la Hugging Face și, de asemenea, coautor al cărții O'Reilly [Natural Language Processing with Transformers] (https://www.oreilly.com/library/view/natural-language-processing/9781098136789/). El are mai mulți ani de experiență în industrie, aducând proiecte NLP în stadiul de producție, lucrând pe întreaga stivă de învățare automată. + +## FAQ[[faq]] + +Iată câteva răspunsuri la întrebări frecvente: + +- **Acest curs permite obținerea unei certificări?** +Deocamdată nu avem nicio certificare pentru acest curs. Cu toate acestea, lucrăm la un program de certificare pentru ecosistemul Hugging Face - rămâneți pe fază! + +- **Cât timp ar trebui să dedic acestui curs?** +Fiecare capitol din acest curs este conceput pentru a fi parcurs într-o săptămână, cu aproximativ 6-8 ore de lucru pe săptămână. Cu toate acestea, vă puteți lua cât timp aveți nevoie pentru a finaliza cursul. + +- **Unde pot să pun o întrebare dacă am una?** +Dacă aveți o întrebare despre orice secțiune a cursului, faceți clic pe bannerul „*Pune o întrebare*” din partea de sus a paginii pentru a fi redirecționat automat către secțiunea corectă a [[Hugging Face forums](https://discuss.huggingface.co/): + +Link to the Hugging Face forums + +Rețineți că o listă de [idei de proiecte](https://discuss.huggingface.co/c/course/course-event/25) este de asemenea disponibilă pe forumuri dacă doriți să practicați mai mult după ce ați terminat cursul. + +- **De unde pot obține codul pentru curs?** +Pentru fiecare secțiune, faceți clic pe bannerul din partea de sus a paginii pentru a rula codul în Google Colab sau Amazon SageMaker Studio Lab: + +Link to the Hugging Face course notebooks + +Caietele Jupyter care conțin tot codul din curs sunt găzduite în repo-ul [`huggingface/notebooks`](https://github.com/huggingface/notebooks). Dacă doriți să le generați local, consultați instrucțiunile din repo-ul [`course`](https://github.com/huggingface/course#-jupyter-notebooks) de pe GitHub. + + +- **Cum pot contribui la curs?** +Există multe modalități de a contribui la curs! Dacă găsiți o greșeală de tipar sau o eroare, vă rugăm să creați o cerere în repo-ul [`course`](https://github.com/huggingface/course). Dacă doriți să ajutați la traducerea cursului în limba dumneavoastră maternă, consultați instrucțiunile [aici](https://github.com/huggingface/course#translating-the-course-into-your-language). + +- **Care au fost alegerile făcute pentru fiecare traducere?** +Fiecare traducere are un glosar și un fișier `TRANSLATING.txt` care detaliază alegerile care au fost făcute pentru jargonul de Machine Learning etc. Puteți găsi un exemplu în limba germană [aici](https://github.com/huggingface/course/blob/main/chapters/de/TRANSLATING.txt). + + +- **Pot reutiliza acest curs?** +Desigur! Cursul este distribuit sub licența [Apache 2 license](https://www.apache.org/licenses/LICENSE-2.0.html) cu caracter permisiv. Aceasta înseamnă că trebuie să acordați creditul corespunzător, să furnizați un link către licență și să indicați dacă au fost făcute modificări. Puteți face acest lucru în orice mod rezonabil, dar nu în niciun fel care să sugereze că licențiatorul vă aprobă pe dumneavoastră sau utilizarea dumneavoastră. Dacă doriți să citați cursul, vă rugăm să utilizați următorul BibTeX: + +``` +@misc{huggingfacecourse, + author = {Hugging Face}, + title = {The Hugging Face Course, 2022}, + howpublished = "\url{https://huggingface.co/course}", + year = {2022}, + note = "[Online; accessed ]" +} +``` + +## Let's Go +Sunteți gata să începeți? În acest capitol, veți învăța: + +* Cum să utilizați funcția `pipeline()` pentru a rezolva sarcini NLP precum generarea și clasificarea textului +* Despre arhitectura Transformer +* Cum să faceți distincția între arhitecturile și cazurile de utilizare ale codificatorului, decodificatorului și codificatorului-decodificator. +- Capitolele 9-12 trec dincolo de NLP și explorează modul în care modelele Transformer pot fi utilizate pentru a aborda sarcini din domeniul procesării semnalelor vorbirii și al viziunii computerizate. Pe parcurs, veți învăța cum să construiți și să partajați demo-uri ale modelelor dumneavoastră și cum să le optimizați pentru mediul de producție. Până la sfârșitul acestei părți, veți fi gata să aplicați 🤗 Transformers la (aproape) orice problemă de machine learning! + +Acest curs: + +* Necesită o bună cunoaștere a limbajului Python. +* Este mai bine să fie urmat după un curs introductiv de deep learning, cum ar fi [fast.ai's](https://www.fast.ai/) [Practical Deep Learning for Coders](https://course.fast.ai/) sau unul dintre programele dezvoltate de [DeepLearning.AI](https://www.deeplearning.ai/). +* Nu se așteaptă la cunoștințe anterioare despre [PyTorch](https://pytorch.org/) sau [TensorFlow](https://www.tensorflow.org/), deși o familiaritate cu oricare dintre acestea va fi de ajutor. + +După ce ați completat acest curs, vă recomandăm să accesați [Natural Language Processing Specialization] (https://www.coursera.org/specializations/natural-language-processing?utm_source=deeplearning-ai&utm_medium=institutions&utm_campaign=20211011-nlp-2-hugging_face-page-nlp-refresh) de la DeepLearning.AI, care acoperă o gamă largă de modele NLP clasice, cum ar fi naive Bayes și LSTMs, despre care este bine să știți! + +## Cine suntem noi?[[cine-suntem-noi]] + +Despre autori: + +[**Abubakar Abid**](https://huggingface.co/abidlabs) și-a susținut doctoratul la Stanford în domeniul învățării automate (Machine Learning) aplicate. În timpul doctoratului său, a fondat [Gradio](https://github.com/gradio-app/gradio), o bibliotecă Python open-source care a fost utilizată pentru a construi peste 600.000 de demo-uri de Machine Learning. Gradio a fost achiziționată de Hugging Face, unde Abubakar activează acum ca lider al echipei de Machine Learning. + +[**Matthew Carrigan**](https://huggingface.co/Rocketknight1) este inginer de Machine Learning la Hugging Face. Locuiește în Dublin, Irlanda și a lucrat anterior ca inginer ML la Parse.ly și înainte de asta ca cercetător postdoctoral la Trinity College Dublin. El nu crede că vom ajunge la AGI prin scalarea arhitecturilor existente, dar are mari speranțe în ceea ce privește nemurirea roboților. + +[**Lysandre Debut**](https://huggingface.co/lysandre) este inginer de Machine Learning la Hugging Face și a lucrat la biblioteca 🤗 Transformers încă din primele etape de dezvoltare. Scopul său este de a face NLP accesibil pentru toată lumea prin dezvoltarea de instrumente cu un API foarte simplu. + +[**Sylvain Gugger**](https://huggingface.co/sgugger) este inginer de cercetare în Machine Learning la Hugging Face și unul dintre principalii întreținători ai bibliotecii 🤗 Transformers. Anterior a fost cercetător științific la fast.ai și a fost coautor la _[Deep Learning for Coders with fastai and PyTorch](https://learning.oreilly.com/library/view/deep-learning-for/9781492045519/)_ cu Jeremy Howard. Obiectivul principal al cercetării sale este de a face învățarea profundă mai accesibilă, prin proiectarea și îmbunătățirea tehnicilor care permit modelelor să se antreneze rapid pe resurse limitate. + +[**Dawood Khan**](https://huggingface.co/dawoodkhan82) este inginer de Machine Learning la Hugging Face. Este originar din New York și a absolvit Universitatea din New York, unde a studiat Informatica. După ce a lucrat ca inginer iOS timp de câțiva ani, Dawood a demisionat pentru a înființa Gradio împreună cu colegii săi co-fondatori. Gradio a fost în cele din urmă achiziționat de Hugging Face. + +[**Merve Noyan**](https://huggingface.co/merve) este un susținător al dezvoltatorilor la Hugging Face, lucrând la dezvoltarea de instrumente și la crearea de conținut în jurul acestora pentru a facilita învățarea automată pentru toată lumea. + +[**Lucile Saulnier**](https://huggingface.co/SaulLu) este inginer de Machine Learning la Hugging Face, dezvoltând și susținând utilizarea de instrumente open source. De asemenea, este implicată activ în multe proiecte de cercetare în domeniul procesării limbajului natural, cum ar fi formarea colaborativă și BigScience. + +[**Lewis Tunstall**](https://huggingface.co/lewtun) este inginer de Machine Learning la Hugging Face, concentrându-se pe dezvoltarea de instrumente open-source și pe asigurarea accesibilității acestora pentru întreaga comunitate. De asemenea, este coautor al cărții O'Reilly [Natural Language Processing with Transformers] (https://www.oreilly.com/library/view/natural-language-processing/9781098136789/). + +[**Leandro von Werra**](https://huggingface.co/lvwerra) este inginer de Machine Learning în cadrul echipei open-source de la Hugging Face și, de asemenea, coautor al cărții O'Reilly [Natural Language Processing with Transformers] (https://www.oreilly.com/library/view/natural-language-processing/9781098136789/). El are mai mulți ani de experiență în industrie, aducând proiecte NLP în stadiul de producție, lucrând pe întreaga stivă de învățare automată. + +## FAQ[[faq]] + +Iată câteva răspunsuri la întrebări frecvente: + +- **Acest curs permite obținerea unei certificări?** +Deocamdată nu avem nicio certificare pentru acest curs. Cu toate acestea, lucrăm la un program de certificare pentru ecosistemul Hugging Face - rămâneți pe fază! + +- **Cât timp ar trebui să dedic acestui curs?** +Fiecare capitol din acest curs este conceput pentru a fi parcurs într-o săptămână, cu aproximativ 6-8 ore de lucru pe săptămână. Cu toate acestea, vă puteți lua cât timp aveți nevoie pentru a finaliza cursul. + +- **Unde pot să pun o întrebare dacă am una?** +Dacă aveți o întrebare despre orice secțiune a cursului, faceți clic pe bannerul „*Pune o întrebare*” din partea de sus a paginii pentru a fi redirecționat automat către secțiunea corectă a [[Hugging Face forums](https://discuss.huggingface.co/): + +Link to the Hugging Face forums + +Rețineți că o listă de [idei de proiecte](https://discuss.huggingface.co/c/course/course-event/25) este de asemenea disponibilă pe forumuri dacă doriți să practicați mai mult după ce ați terminat cursul. + +- **De unde pot obține codul pentru curs?** +Pentru fiecare secțiune, faceți clic pe bannerul din partea de sus a paginii pentru a rula codul în Google Colab sau Amazon SageMaker Studio Lab: + +Link to the Hugging Face course notebooks + +Caietele Jupyter care conțin tot codul din curs sunt găzduite în repo-ul [`huggingface/notebooks`](https://github.com/huggingface/notebooks). Dacă doriți să le generați local, consultați instrucțiunile din repo-ul [`course`](https://github.com/huggingface/course#-jupyter-notebooks) de pe GitHub. + + +- **Cum pot contribui la curs?** +Există multe modalități de a contribui la curs! Dacă găsiți o greșeală de tipar sau o eroare, vă rugăm să creați o cerere în repo-ul [`course`](https://github.com/huggingface/course). Dacă doriți să ajutați la traducerea cursului în limba dumneavoastră maternă, consultați instrucțiunile [aici](https://github.com/huggingface/course#translating-the-course-into-your-language). + +- **Care au fost alegerile făcute pentru fiecare traducere?** +Fiecare traducere are un glosar și un fișier `TRANSLATING.txt` care detaliază alegerile care au fost făcute pentru jargonul de Machine Learning etc. Puteți găsi un exemplu în limba germană [aici](https://github.com/huggingface/course/blob/main/chapters/de/TRANSLATING.txt). + + +- **Pot reutiliza acest curs?** +Desigur! Cursul este distribuit sub licența [Apache 2 license](https://www.apache.org/licenses/LICENSE-2.0.html) cu caracter permisiv. Aceasta înseamnă că trebuie să acordați creditul corespunzător, să furnizați un link către licență și să indicați dacă au fost făcute modificări. Puteți face acest lucru în orice mod rezonabil, dar nu în niciun fel care să sugereze că licențiatorul vă aprobă pe dumneavoastră sau utilizarea dumneavoastră. Dacă doriți să citați cursul, vă rugăm să utilizați următorul BibTeX: + +``` +@misc{huggingfacecourse, + author = {Hugging Face}, + title = {The Hugging Face Course, 2022}, + howpublished = "\url{https://huggingface.co/course}", + year = {2022}, + note = "[Online; accessed ]" +} +``` + +## Let's Go +Sunteți gata să începeți? În acest capitol, veți învăța: + +* Cum să utilizați funcția `pipeline()` pentru a rezolva sarcini NLP precum generarea și clasificarea textului +* Despre arhitectura Transformer +* Cum să faceți distincția între arhitecturile și cazurile de utilizare ale codificatorului, decodificatorului și codificatorului-decodificatort From 70ea3206bdbba833eece8c0ef9a18003c6581f33 Mon Sep 17 00:00:00 2001 From: "ludmila.friptu" Date: Mon, 7 Oct 2024 19:55:30 +0300 Subject: [PATCH 003/167] Add chapter 1 translated --- chapters/rum/chapter1/1.mdx | 2 +- chapters/rum/chapter1/10.mdx | 258 +++++++++++++++++++++++++++ chapters/rum/chapter1/2.mdx | 26 +++ chapters/rum/chapter1/3.mdx | 326 +++++++++++++++++++++++++++++++++++ chapters/rum/chapter1/4.mdx | 178 +++++++++++++++++++ chapters/rum/chapter1/5.mdx | 22 +++ chapters/rum/chapter1/6.mdx | 21 +++ chapters/rum/chapter1/7.mdx | 20 +++ chapters/rum/chapter1/8.mdx | 31 ++++ chapters/rum/chapter1/9.mdx | 16 ++ 10 files changed, 899 insertions(+), 1 deletion(-) create mode 100644 chapters/rum/chapter1/10.mdx create mode 100644 chapters/rum/chapter1/2.mdx create mode 100644 chapters/rum/chapter1/3.mdx create mode 100644 chapters/rum/chapter1/4.mdx create mode 100644 chapters/rum/chapter1/5.mdx create mode 100644 chapters/rum/chapter1/6.mdx create mode 100644 chapters/rum/chapter1/7.mdx create mode 100644 chapters/rum/chapter1/8.mdx create mode 100644 chapters/rum/chapter1/9.mdx diff --git a/chapters/rum/chapter1/1.mdx b/chapters/rum/chapter1/1.mdx index 4e00b799a..c4d8a71a3 100644 --- a/chapters/rum/chapter1/1.mdx +++ b/chapters/rum/chapter1/1.mdx @@ -1,4 +1,4 @@ -# Introducere[[introduction]] +# Introducere[[introducere]] + +# Quiz de sfârșit de capitol[[test-de-sfârșit-de-capitol]] + + + +Acest capitol a acoperit o mulțime de subiecte! Nu vă faceți griji dacă nu ați înțeles toate detaliile; capitolele următoare vă vor ajuta să înțelegeți cum funcționează lucrurile în mecanismele lor interne. + +Mai întâi, însă, să testăm ceea ce ați învățat în acest capitol! + + +### 1. Explorați Hub-ul și căutați checkpoint-ul `roberta-large-mnli`. Ce sarcină îndeplinește acesta? + + +roberta-large-mnli page." + }, + { + text: "Text classification", + explain: "More precisely, it classifies if two sentences are logically linked across three labels (contradiction, neutral, entailment) — a task also called natural language inference.", + correct: true + }, + { + text: "Text generation", + explain: "Look again on the roberta-large-mnli page." + } + ]} +/> + +### 2. Ce va returna următorul cod? + +```py +from transformers import pipeline + +ner = pipeline("ner", grouped_entities=True) +ner("My name is Sylvain and I work at Hugging Face in Brooklyn.") +``` + +sentiment-analysis pipeline." + }, + { + text: "It will return a generated text completing this sentence.", + explain: "This is incorrect — it would be a text-generation pipeline.", + }, + { + text: "It will return the words representing persons, organizations or locations.", + explain: "Furthermore, with grouped_entities=True, it will group together the words belonging to the same entity, like \"Hugging Face\".", + correct: true + } + ]} +/> + +### 3. Ce ar trebui să înlocuiască ... în acest exemplu de cod? + +```py +from transformers import pipeline + +filler = pipeline("fill-mask", model="bert-base-cased") +result = filler("...") +``` + + has been waiting for you.", + explain: "This is incorrect. Check out the bert-base-cased model card and try to spot your mistake." + }, + { + text: "This [MASK] has been waiting for you.", + explain: "Correct! This model's mask token is [MASK].", + correct: true + }, + { + text: "This man has been waiting for you.", + explain: "This is incorrect. This pipeline fills in masked words, so it needs a mask token somewhere." + } + ]} +/> + +### 4. De ce nu va funcționa acest cod? + +```py +from transformers import pipeline + +classifier = pipeline("zero-shot-classification") +result = classifier("This is a course about the Transformers library") +``` + +candidate_labels=[...].", + correct: true + }, + { + text: "This pipeline requires several sentences, not just one.", + explain: "This is incorrect, though when properly used, this pipeline can take a list of sentences to process (like all other pipelines)." + }, + { + text: "The 🤗 Transformers library is broken, as usual.", + explain: "We won't dignify this answer with a comment!" + }, + { + text: "This pipeline requires longer inputs; this one is too short.", + explain: "This is incorrect. Note that a very long text will be truncated when processed by this pipeline." + } + ]} +/> + +### 5. Ce înseamnă „învățarea prin transfer”? + + + +### 6. Adevărat sau fals? De obicei, un model lingvistic nu are nevoie de etichete pentru preinstruire. + +self-supervised, which means the labels are created automatically from the inputs (like predicting the next word or filling in some masked words).", + correct: true + }, + { + text: "False", + explain: "Incorrect." + } + ]} +/> + +### 7. Selectați propoziția care descrie cel mai bine termenii „model”, „arhitectură” și „ greutăți”. + + + + +### 8. Care dintre aceste tipuri de modele le-ați folosi pentru a completa prompt-urile cu text generat? + + + +### 9. Care dintre aceste tipuri de modele le-ați folosi pentru a rezuma texte? + + + +### 10. Care dintre aceste tipuri de modele le-ați utiliza pentru a clasifica intrările de text în funcție de anumite etichete? + + + +### 11. Ce sursă posibilă poate avea prejudecata observată într-un model? + + diff --git a/chapters/rum/chapter1/2.mdx b/chapters/rum/chapter1/2.mdx new file mode 100644 index 000000000..2fb20b831 --- /dev/null +++ b/chapters/rum/chapter1/2.mdx @@ -0,0 +1,26 @@ +# Procesarea limbajului natural[[procesarea-limbajului-natural]] + + + +Înainte de a trece la modelele Transformer, haideți să facem o prezentare scurtă despre ce este procesarea limbajului natural și de ce ne interesează. + +## Ce este NLP?[[ce-este-nlp]] + +NLP este un domeniu al lingvisticii și al învățării automate axat pe înțelegerea a tot ceea ce este legat de limbajul uman. Scopul sarcinilor NLP nu este doar înțelegerea individuală a cuvintelor, ci și capacitatea de a înțelege contextul acelor cuvinte. + +În continuare este prezentată o listă a sarcinilor obișnuite de NLP, cu câteva exemple pentru fiecare: + +- **Clasificarea propozițiilor întregi**: Determinarea caracterului unei recenzii, detectarea dacă un e-mail este spam, determinarea dacă o propoziție este corectă gramatical sau dacă două propoziții sunt legate logic sau nu +- **Clasificarea fiecărui cuvânt dintr-o propoziție**: Identificarea componentelor gramaticale ale unei propoziții (substantiv, verb, adjectiv) sau a entităților nominalizate (persoană, locație, organizație) +- **Generarea conținutului de text**: Completarea unui text generat automat, completarea spațiilor goale dintr-un text cu cuvinte ascunse +- **Extragerea unui răspuns dintr-un text**:Având o întrebare și un context, se extrage răspunsul la întrebare pe baza informațiilor furnizate în context +- **Generarea unei propoziții noi dintr-un text de intrare**: Traducerea unui text într-o altă limbă, rezumarea textului + +NLP nu se limitează însă la textul scris. NLP, de asemenea, abordează provocări complexe în domeniul recunoașterii vorbirii și al viziunii computerizate, cum ar fi generarea unei transcrieri a unui fragment audio sau a unei descrieri a unei imagini. + +## De ce este o provocare?[[de-ce-este-o-provocare]] + +Computerele nu procesează informațiile în același mod ca oamenii. De exemplu, atunci când citim propoziția „Mi-e foame”, îi putem înțelege cu ușurință semnificația. În mod similar, având în vedere două propoziții precum „mi-e foame” și „sunt trist”, suntem capabili să determinăm cu ușurință cât de asemănătoare sunt acestea. Pentru modelele de învățare automată (ML), astfel de sarcini sunt mai dificile. Textul trebuie prelucrat într-un mod care să permită modelului să învețe din el. Și deoarece limbajul este complex, trebuie să ne gândim cu atenție la modul în care trebuie efectuată această procesare. Au fost efectuate numeroase cercetări cu privire la modul de reprezentare a textului și vom analiza câteva metode în capitolul următor. diff --git a/chapters/rum/chapter1/3.mdx b/chapters/rum/chapter1/3.mdx new file mode 100644 index 000000000..91803fb0a --- /dev/null +++ b/chapters/rum/chapter1/3.mdx @@ -0,0 +1,326 @@ +# Ce pot face modelele Transformer[[ce-pot-face-modelele-transformer]] + + + +În această parte, vom vedea ce pot face modelele Transformer și vom folosi primul nostru instrument din biblioteca 🤗 Transformers: funcția `pipeline()`. + + +👀 Vedeți butonul Open in Colab din dreapta sus? Faceți clic pe el pentru a deschide un notebook Google Colab cu toate exemplele de cod din această secțiune. Acest buton va fi prezent în orice secțiune care conține exemple de cod. +Dacă doriți să executați exemplele local, vă recomandăm să aruncați o privire la setup. + + +## Modelele Transformer sunt peste tot![[modelele-transformer-sunt-peste-tot]] + +Modelele Transformer sunt utilizate pentru a rezolva toate tipurile de sarcini NLP, precum cele menționate în secțiunea anterioară. Iată câteva dintre companiile și organizațiile care utilizează modelele Hugging Face și Transformer, care de asemenea contribuie la dezvoltarea comunității prin partajarea modelelor lor: + +Companies using Hugging Face + +Biblioteca [🤗 Transformers](https://github.com/huggingface/transformers) oferă funcționalitatea de a crea și utiliza aceste modele partajate. [Model Hub](https://huggingface.co/models) conține mii de modele preinstruite pe care oricine le poate descărca și utiliza. De asemenea, vă puteți încărca propriile modele pe Hub! + + +⚠️ Hub-ul Hugging Face nu este limitat la modelele Transformer. Oricine poate partaja orice fel de modele sau seturi de date pe care le dorește! Creați un cont huggingface.co pentru a beneficia de toate funcțiile disponibile! + + +Înainte de a analiza funcționarea internă a modelelor Transformer , să ne oprim asupra unor exemple privind modul în care acestea pot fi utilizate pentru a rezolva unele probleme interesante de NLP. + +## Lucrul cu pipelines[[lucrul-cu-pipelines]] + + + +Obiectul cel mai elementar din biblioteca 🤗 Transformers este funcția `pipeline()`. Aceasta conectează un model cu etapele sale necesare de preprocesare și postprocesare, permițându-ne să introducem direct orice text și să obținem un răspuns inteligibil: + +```python +from transformers import pipeline + +classifier = pipeline("sentiment-analysis") +classifier("I've been waiting for a HuggingFace course my whole life.") +``` + +```python out +[{'label': 'POSITIVE', 'score': 0.9598047137260437}] +``` + +Putem adăuga chiar și mai multe propoziții! + +```python +classifier( + ["I've been waiting for a HuggingFace course my whole life.", "I hate this so much!"] +) +``` + +```python out +[{'label': 'POSITIVE', 'score': 0.9598047137260437}, + {'label': 'NEGATIVE', 'score': 0.9994558095932007}] +``` + +În mod implicit, aceast pipeline selectează un anumit model preinstruit care a fost ajustat pentru a analiza emoțiile dintr-un text în limba engleză. Modelul este descărcat și pus în cache atunci când creați obiectul `classifier`. Dacă rulați din nou comanda, modelul din memoria cache va fi utilizat în locul acestuia și nu este nevoie să descărcați din nou modelul. + +Atunci când transmiteți un text către un pipeline, sunt necesari trei pași: + +1. Textul este preprocesat într-un format pe care modelul îl poate înțelege. +2. Datele de intrare preprocesate sunt transmise modelului. +3. Predicțiile modelului sunt postprocesate, astfel încât să le puteți înțelege. + + +Unele dintre [pipeline-urile disponibile] în prezent (https://huggingface.co/transformers/main_classes/pipelines) sunt: + +- `feature-extraction` (obține reprezentarea vectorială a unui text) +- `fill-mask` +- `ner` (recunoașterea NE (named entity)) +- `question-answering` +- `sentiment-analysis` +- `summarization` +- `text-generation` +- `translation` +- `zero-shot-classification` + +Să aruncăm o privire la câteva dintre ele! + +## Zero-shot classification[zero-shot-classification]] + +Vom începe prin a aborda o sarcină mai dificilă în care trebuie să clasificăm texte care nu au fost etichetate. Acesta este un scenariu comun în proiectele din lumea reală, deoarece adnotarea textului este de obicei costisitoare în timp și necesită expertiză în domeniu. Pentru acest caz de utilizare, pipeline-ul `zero-shot-classification` este foarte puternică: vă permite să specificați ce etichete să utilizați pentru clasificare, astfel încât să nu trebuie să vă bazați pe etichetele modelului preinstruit. Ați văzut deja cum modelul poate clasifica o propoziție ca fiind pozitivă sau negativă folosind aceste două etichete - dar poate, de asemenea, clasifica textul folosind orice alt set de etichete doriți. + +```python +from transformers import pipeline + +classifier = pipeline("zero-shot-classification") +classifier( + "This is a course about the Transformers library", + candidate_labels=["education", "politics", "business"], +) +``` + +```python out +{'sequence': 'This is a course about the Transformers library', + 'labels': ['education', 'business', 'politics'], + 'scores': [0.8445963859558105, 0.111976258456707, 0.043427448719739914]} +``` + +Aceast pipeline se numește _zero-shot_ deoarece nu trebuie să reglați modelul pe datele dvs. pentru a o utiliza. Aceasta poate returna direct scoruri de probabilitate pentru orice listă de etichete doriți! + + + +✏️ **Încercați** Jucați-vă cu propriile secvențe și etichete și vedeți cum se comportă modelul. + + + + +## Text generation[[text-generation]] + +Să vedem acum cum se utilizează un pipeline pentru a genera un text. Ideea principală aici este că furnizați o solicitare, iar modelul o va completa automat prin generarea textului rămas. Acest lucru este similar cu funcția de text previzibil care se găsește pe multe telefoane. Generarea textului implică caracter aleatoriu, deci este normal să nu obțineți aceleași rezultate ca cele prezentate mai jos. + +```python +from transformers import pipeline + +generator = pipeline("text-generation") +generator("In this course, we will teach you how to") +``` + +```python out +[{'generated_text': 'In this course, we will teach you how to understand and use ' + 'data flow and data interchange when handling user data. We ' + 'will be working with one or more of the most commonly used ' + 'data flows — data flows of various types, as seen by the ' + 'HTTP'}] +``` + +Puteți controla câte secvențe diferite sunt generate cu argumentul `num_return_sequences` și lungimea totală a textului de ieșire cu argumentul `max_length`. + + + +✏️ **Încercați!** Utilizați argumentele `num_return_sequences` și `max_length` pentru a genera două propoziții a câte 15 cuvinte fiecare. + + + + +## Utilizarea oricărui model de pe Hub într-un pipeline[[utilizarea-oricărui-model-de-pe-hub-într-un-pipeline]] + +Exemplele anterioare au utilizat modelul implicit pentru sarcina în cauză, dar puteți alege, de asemenea, un anumit model din Hub pentru a-l utiliza într-un pipeline pentru o sarcină specifică - de exemplu, generarea de text. Accesați [Model Hub](https://huggingface.co/models) și faceți clic pe eticheta corespunzătoare din stânga pentru a afișa numai modelele acceptate pentru sarcina respectivă. Ar trebui să ajungeți la o pagină precum [aceasta](https://huggingface.co/models?pipeline_tag=text-generation). + +Să încercăm modelul [`distilgpt2`](https://huggingface.co/distilgpt2)! Iată cum să îl încărcați în același pipeline ca înainte: + +```python +from transformers import pipeline + +generator = pipeline("text-generation", model="distilgpt2") +generator( + "In this course, we will teach you how to", + max_length=30, + num_return_sequences=2, +) +``` + +```python out +[{'generated_text': 'In this course, we will teach you how to manipulate the world and ' + 'move your mental and physical capabilities to your advantage.'}, + {'generated_text': 'In this course, we will teach you how to become an expert and ' + 'practice realtime, and with a hands on experience on both real ' + 'time and real'}] +``` + +Puteți să vă îmbunătățiți căutarea unui model făcând clic pe tag-urile de limbaj și să alegeți un model care va genera text în altă limbă. Model Hub conține chiar și puncte de control pentru modele multilingve care acceptă mai multe limbi. + +După ce selectați un model făcând clic pe el, veți vedea că există un widget care vă permite să îl încercați direct online. În acest fel, puteți testa rapid capacitățile modelului înainte de a-l descărca. + + + +✏️ ** Încercați!** Utilizați filtrele pentru a găsi un model de generare a textului pentru o altă limbă. Nu ezitați să vă jucați cu widget-ul și să îl utilizați într-un pipeline! + + + +### API-ul de inferență[[api-ul-de-inferență]] + +Toate modelele pot fi testate direct prin browser utilizând API-ul de inferență, care este disponibil pe site-ul Hugging Face [website] (https://huggingface.co/). Vă puteți juca cu modelul direct pe această pagină introducând text personalizat și urmărind cum modelul procesează datele de intrare. + +API-ul de inferență care alimentează widget-ul este, de asemenea, disponibil ca produs plătit, ceea ce este util dacă aveți nevoie de el pentru fluxurile dvs. de lucru. Consultați [pagina de prețuri](https://huggingface.co/pricing) pentru mai multe detalii. + +## Mask filling[[mask-filling]] + +Următorul pipeline pe care il veți încerca este `fill-mask`. Ideea acestei sarcini este de a completa golurile dintr-un text dat: + +```python +from transformers import pipeline + +unmasker = pipeline("fill-mask") +unmasker("This course will teach you all about models.", top_k=2) +``` + +```python out +[{'sequence': 'This course will teach you all about mathematical models.', + 'score': 0.19619831442832947, + 'token': 30412, + 'token_str': ' mathematical'}, + {'sequence': 'This course will teach you all about computational models.', + 'score': 0.04052725434303284, + 'token': 38163, + 'token_str': ' computational'}] +``` + +Argumentul `top_k` controlează câte posibilități doriți să fie afișate. Rețineți că aici modelul completează cuvântul special ``, care este adesea denumit *mask token*. Alte modele de umplere a măștii ar putea avea token-uri de mască diferite, astfel încât este întotdeauna bine să verificați cuvântul de mască adecvat atunci când explorați alte modele. O modalitate de verificare este să vă uitați la cuvântul mască utilizat în widget. + + + +✏️ **Încercați!** Căutați modelul `bert-base-cased` pe Hub și identificați-i cuvântul mască în widget-ul Inference API. Ce prezice acest model pentru propoziția din exemplul nostru `pipeline` de mai sus? + + + +## Recunoașterea NE (named entity)[[recunoașterea-NE]] + +Recunoașterea (NE) este o sarcină în care modelul trebuie să găsească care părți din textul de intrare corespund unor entități precum persoane, locații sau organizații. Să ne uităm la un exemplu: + +```python +from transformers import pipeline + +ner = pipeline("ner", grouped_entities=True) +ner("My name is Sylvain and I work at Hugging Face in Brooklyn.") +``` + +```python out +[{'entity_group': 'PER', 'score': 0.99816, 'word': 'Sylvain', 'start': 11, 'end': 18}, + {'entity_group': 'ORG', 'score': 0.97960, 'word': 'Hugging Face', 'start': 33, 'end': 45}, + {'entity_group': 'LOC', 'score': 0.99321, 'word': 'Brooklyn', 'start': 49, 'end': 57} +] +``` + +Aici, modelul a identificat corect că Sylvain este o persoană (PER), Hugging Face o organizație (ORG), iar Brooklyn o locație (LOC). + +Trecem opțiunea `grouped_entities=True` în funcția de creare a pipeline-ului pentru a-i spune pipeline-ului să regrupeze părțile propoziției care corespund aceleiași entități: aici, modelul a grupat corect „Hugging” și „Face” ca o singură organizație, chiar dacă numele este format din mai multe cuvinte. De fapt, după cum vom vedea în capitolul următor, preprocesarea chiar împarte unele cuvinte în părți mai mici. De exemplu, `Sylvain` este împărțit în patru părți: `S`, `##yl`, `##va`, și `##in`. În etapa de postprocesare, pipeline-ul a reușit să regrupeze aceste părți. + + + +✏️ **Încercați!** Căutați în Hub-ul de modele un model capabil să facă etichetarea părții de vorbire (de obicei abreviată ca POS) în limba engleză. Ce prezice acest model pentru propoziția din exemplul de mai sus? + + + +## Question answering[[question-answering]] + +Pipeline-ul "question-answering" răspunde la întrebări folosind informații dintr-un context dat: + +```python +from transformers import pipeline + +question_answerer = pipeline("question-answering") +question_answerer( + question="Where do I work?", + context="My name is Sylvain and I work at Hugging Face in Brooklyn", +) +``` + +```python out +{'score': 0.6385916471481323, 'start': 33, 'end': 45, 'answer': 'Hugging Face'} +``` + +Rețineți că acest pipeline funcționează prin extragerea informațiilor din contextul furnizat; el nu generează răspunsul. + +## Summarization[[summarization]] + +Rezumarea este sarcina de a reduce un text într-un altul mai scurt, păstrând toate (sau majoritatea) aspectelor importante menționate în el. Iată un exemplu: + +```python +from transformers import pipeline + +summarizer = pipeline("summarization") +summarizer( + """ + America has changed dramatically during recent years. Not only has the number of + graduates in traditional engineering disciplines such as mechanical, civil, + electrical, chemical, and aeronautical engineering declined, but in most of + the premier American universities engineering curricula now concentrate on + and encourage largely the study of engineering science. As a result, there + are declining offerings in engineering subjects dealing with infrastructure, + the environment, and related issues, and greater concentration on high + technology subjects, largely supporting increasingly complex scientific + developments. While the latter is important, it should not be at the expense + of more traditional engineering. + + Rapidly developing economies such as China and India, as well as other + industrial countries in Europe and Asia, continue to encourage and advance + the teaching of engineering. Both China and India, respectively, graduate + six and eight times as many traditional engineers as does the United States. + Other industrial countries at minimum maintain their output, while America + suffers an increasingly serious decline in the number of engineering graduates + and a lack of well-educated engineers. +""" +) +``` + +```python out +[{'summary_text': ' America has changed dramatically during recent years . The ' + 'number of engineering graduates in the U.S. has declined in ' + 'traditional engineering disciplines such as mechanical, civil ' + ', electrical, chemical, and aeronautical engineering . Rapidly ' + 'developing economies such as China and India, as well as other ' + 'industrial countries in Europe and Asia, continue to encourage ' + 'and advance engineering .'}] +``` + +La fel ca în cazul generării de text, puteți specifica o lungime `max_length` sau `min_length` pentru rezultat. + +## Translation[[translation]] + +Pentru traducere, puteți utiliza un model predefinit dacă introduceți o combinație de limbi în numele sarcinii (cum ar fi `„translation_en_to_fr”`), dar cel mai simplu este să alegeți modelul pe care doriți să îl utilizați în [Model Hub](https://huggingface.co/models). Aici vom încerca să traducem din franceză în engleză: + +```python +from transformers import pipeline + +translator = pipeline("translation", model="Helsinki-NLP/opus-mt-fr-en") +translator("Ce cours est produit par Hugging Face.") +``` + +```python out +[{'translation_text': 'This course is produced by Hugging Face.'}] +``` + +Ca și în cazul generării și rezumării textului, puteți specifica `max_length` sau `min_length` pentru rezultat. + + +✏️ **Incercați!** Căutați modele de traducere în alte limbi și încercați să traduceți propoziția anterioară în câteva limbi diferite. + + + +Pipeline-urile prezentate până în acest moment au în principal scop demonstrativ. Ele au fost programate pentru sarcini specifice și nu pot efectua variații ale acestora. În capitolul următor, veți afla ce se află în interiorul unei funcții `pipeline()` și cum să îi personalizați comportamentul. \ No newline at end of file diff --git a/chapters/rum/chapter1/4.mdx b/chapters/rum/chapter1/4.mdx new file mode 100644 index 000000000..6fb2bdcdb --- /dev/null +++ b/chapters/rum/chapter1/4.mdx @@ -0,0 +1,178 @@ +# Cum funcționează Transformers?[[cum-funcționează-transformers]] + + + +În această secțiune, vom analiza arhitectura modelelor Transformer. + +## Un pic despre istorie modelelor Transformer[[un-pic-despre-istoria-modelelor-transformer]] + +Iată câteva puncte de referință în (scurta) istorie a modelelor Transformer: + +
+A brief chronology of Transformers models. + +
+ +[Arhitectura Transformer] (https://arxiv.org/abs/1706.03762) a fost introdusă în iunie 2017. Accentul cercetării inițiale a fost pus pe sarcinile de traducere. Aceasta a fost urmată de introducerea mai multor modele influente, inclusiv: + +- **Iunie 2018**: [GPT](https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf), primul model Transformer preinstruit, utilizat pentru reglarea precisă a diferitelor sarcini NLP și a obținut rezultate de top + +- **Octombrie 2018**: [BERT](https://arxiv.org/abs/1810.04805), un alt model mare preinstruit, conceput pentru a produce rezumate mai bune ale propozițiilor (mai multe despre el în capitolul următor!) + +- **Februarie 2019**: [GPT-2](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf), o versiune îmbunătățită (și mai mare) a GPT care nu a fost lansată public imediat din motive etice + +- **Octombrie 2019**: [DistilBERT](https://arxiv.org/abs/1910.01108), o versiune rafinată a BERT care este cu 60% mai rapidă, cu 40% mai ușoară în memorie și care păstrează încă 97% din performanța BERT + +- **Octombrie 2019**: [BART](https://arxiv.org/abs/1910.13461) și [T5](https://arxiv.org/abs/1910.10683), două modele mari preinstruite folosind aceeași arhitectură ca modelul original Transformer (primul care face acest lucru) + +- **Mai 2020**, [GPT-3](https://arxiv.org/abs/2005.14165), o versiune și mai mare a GPT-2, care este capabilă să se descurce bine într-o varietate de sarcini, fără a fi nevoie de o reglare fină (numită _zero-shot learning_) + +Această listă este departe de a fi completă și este menită doar să evidențieze câteva dintre diferitele tipuri de modele Transformer. În linii mari, acestea pot fi grupate în trei categorii: + +- Tip GPT (numite și modele de Transformer autoregresive) +- Tip BERT (numite și modele de Transfomer _auto-encoding_) +- Tip BART/T5 (denumite și modele de Transformer _sequence-to-sequence_) + +Vom analiza aceste familii în detaliu mai târziu. + +##Transformers sunt modele de limbaj[transformers-sunt-modele-de-limbaj]] + +Toate modelele Transformer menționate mai sus (GPT, BERT, BART, T5 etc.) au fost antrenate ca *modele lingvistice*. Aceasta înseamnă că au fost antrenate pe volume mari de text brut într-un mod autosupravegheat. Învățarea autosupravegheată este un tip de formare în care obiectivul este calculat automat din datele de intrare ale modelului. Aceasta înseamnă că nu este nevoie de oameni pentru a eticheta datele! + +Acest tip de model dezvoltă o înțelegere statistică a limbii pe care a fost antrenat, dar nu este foarte util pentru sarcini practice specifice. Din acest motiv, modelul general preinstruit trece apoi printr-un proces numit *transfer learning*. În timpul acestui proces, modelul este ajustat într-un mod supravegheat - adică folosind etichete notate de oameni - pentru o anumită sarcină. + +Un exemplu de sarcină este prezicerea următorului cuvânt dintr-o propoziție după citirea a *n* cuvinte anterioare. Aceasta se numește *modelare cauzală a limbajului* deoarece rezultatul depinde de intrările trecute și prezente, dar nu și de cele viitoare. + +
+Example of causal language modeling in which the next word from a sentence is predicted. + +
+ +Un alt exemplu este *modelarea limbajului mascat*, în care modelul prezice un cuvânt mascat din propoziție. + +
+Example of masked language modeling in which a masked word from a sentence is predicted. + +
+ +## Modelele Transformer sunt mari[[modelele-transformer-sunt-mari]] + +Cu excepția câtorva cazuri excepționale (cum ar fi DistilBERT), strategia generală pentru a obține performanțe mai bune constă în creșterea dimensiunilor modelelor, precum și a cantității de date pe care acestea sunt preinstruite. + +
+Number of parameters of recent Transformers models +
+ +Din păcate, antrenarea unui model, în special a unuia mare, necesită o cantitate mare de date. Acest lucru devine foarte costisitor în termeni de timp și resurse de calcul. Aceasta se reflectă chiar și în impactul asupra mediului, după cum se poate vedea în graficul următor. + +
+The carbon footprint of a large language model. + +
+ + + +Iar acest lucru arată un proiect pentru un model (foarte mare) condus de o echipă care încearcă în mod conștient să reducă impactul de mediu al preinstruirii. Amprenta lăsată de efectuarea multor teste pentru a obține cei mai buni hiperparametri ar fi și mai mare. + +Imaginați-vă dacă de fiecare dată când o echipă de cercetare, o organizație studențească sau o companie ar dori să antreneze un model, ar face-o de la zero. Acest lucru ar conduce la costuri globale uriașe și inutile! + +Acesta este motivul pentru care partajarea modelelor lingvistice este esențială: partajarea ponderilor antrenate și construirea pe baza ponderilor deja antrenate reduce costul global de calcul și amprenta de carbon a comunității. + +Apropo, puteți evalua amprenta de carbon a formării modelelor dvs. prin intermediul mai multor instrumente. De exemplu [ML CO2 Impact](https://mlco2.github.io/impact/) sau [Code Carbon]( https://codecarbon.io/) care este integrat în 🤗 Transformers. Pentru a afla mai multe despre acest lucru, puteți citi această [postare pe blog](https://huggingface.co/blog/carbon-emissions-on-the-hub) care vă va arăta cum să generați un fișier `emissions.csv` cu o estimare a amprentei formării dvs., precum și [documentația](https://huggingface.co/docs/hub/model-cards-co2) din 🤗 Transformers care abordează acest subiect. + + +## Transfer Learning[[transfer-learning]] + + + +*Preinstruirea* este acțiunea de formare a unui model de la zero: ponderile sunt inițializate aleatoriu, iar formarea începe fără nicio cunoaștere prealabilă. + +
+The pretraining of a language model is costly in both time and money. + +
+ +Această preinstruire se face de obicei pe cantități foarte mari de date. Prin urmare, este nevoie de un corpus foarte mare de date, iar formarea poate dura până la câteva săptămâni. + +*Reglarea-fină*, pe de altă parte, este instruirea efectuată **după** ce un model a fost preinstruit. Pentru a efectua reglarea fină, obțineți mai întâi un model lingvistic preinstruit, apoi efectuați o instruire suplimentară cu un set de date specific sarcinii dumneavoastră. Stați - de ce să nu instruiți de la început modelul pentru cazul dvs. final de utilizare (**scratch**)? Există câteva motive: + +* Modelul preinstruit a fost deja instruit pe un set de date care are unele similitudini cu setul de date pentru reglarea fină. Procesul de reglare fină este astfel capabil să profite de cunoștințele dobândite de modelul inițial în timpul preantrenării (de exemplu, în cazul problemelor de NLP, modelul preantrenat va avea un anumit tip de înțelegere statistică a limbajului pe care îl utilizați pentru sarcina dumneavoastră). +* Deoarece modelul preinstruit a fost deja instruit pe o mulțime de date, reglarea fină necesită mult mai puține date pentru a obține rezultate decente. +* Din același motiv, timpul și resursele necesare pentru a obține rezultate bune sunt mult mai reduse. + +De exemplu, se poate valorifica un model preformat antrenat pe limba engleză și apoi ajustat pe un corpus arXiv, rezultând un model bazat pe știință/cercetare. Reglarea fină va necesita doar o cantitate limitată de date: cunoștințele dobândite de modelul pre-format sunt „transferate”, de unde și termenul de *învățare prin transfer*. + +
+The fine-tuning of a language model is cheaper than pretraining in both time and money. + +
+ +Prin urmare, reglarea fină a unui model are costuri mai mici de timp, date, financiare și de mediu. De asemenea, este mai rapid și mai ușor să iterați pe diferite scheme de reglaj fin, deoarece formarea este mai puțin constrângătoare decât o preformare completă. + +Acest proces va obține, de asemenea, rezultate mai bune decât formarea de la zero (cu excepția cazului în care dispuneți de o mulțime de date), motiv pentru care ar trebui să încercați întotdeauna să valorificați un model preformat - unul cât mai apropiat posibil de sarcina pe care o aveți la îndemână - și să îl reglați fin. + +## Arhitectura generală[[arhitectura-generală]] + +În această secțiune, vom analiza arhitectura generală a modelului Transformer. Nu vă faceți griji dacă nu înțelegeți anumite concepte; mai târziu există secțiuni detaliate care acoperă fiecare dintre componente. + + + +## Introducere[[introducere]] + +Modelul este compus în principal din două blocuri: + +* **Codificator (stânga)**: Codificatorul primește o intrare și construiește o reprezentare a acesteia (caracteristicile sale). Aceasta înseamnă că modelul este optimizat pentru a dobândi cunoștințe din datele de intrare. +* **Decodificator (dreapta)**: Decodificatorul utilizează reprezentarea codificatorului (caracteristicile) împreună cu alte intrări pentru a genera o secvență țintă. Aceasta înseamnă că modelul este optimizat pentru a genera ieșiri. + +
+Architecture of a Transformers models + +
+ +Fiecare dintre aceste părți poate fi utilizată independent, în funcție de sarcină: + +* **Modeluri exclusiv de codare**: Bune pentru sarcini care necesită înțelegerea datelor de intrare, cum ar fi clasificarea propozițiilor și recunoașterea entităților numite. +* **Modele exclusiv decodificatoare**: Bune pentru sarcini generative, cum ar fi generarea de text. +* **Modele encoder-decoder** sau **modele sequence-to-sequence**: Bune pentru sarcinile generative care necesită o intrare, cum ar fi traducerea sau rezumarea. + +Vom analiza aceste arhitecturi în mod independent în secțiunile următoare. + +## Attention layers(straturi de atenție)[[attention-layers]] + +O caracteristică cheie a modelelor Transformer este faptul că acestea sunt construite cu straturi speciale numite *attention layers*. De fapt, titlul lucrării de prezentare a arhitecturii Transformer a fost [„Attention Is All You Need”] (https://arxiv.org/abs/1706.03762)! Vom explora detaliile attention layers-urilor mai târziu în curs; pentru moment, tot ce trebuie să știți este că acest strat va spune modelului să acorde o atenție specifică anumitor cuvinte din propoziția pe care i-ați transmis-o (și să le ignore mai mult sau mai puțin pe celelalte) atunci când se ocupă de reprezentarea fiecărui cuvânt. + +Pentru a pune acest lucru în context, luați în considerare sarcina de a traduce un text din engleză în franceză. Având în vedere intrarea „Vă place acest curs”, un model de traducere va trebui să se ocupe și de cuvântul adiacent „You” pentru a obține traducerea corectă pentru cuvântul „like”, deoarece în franceză verbul „like” se conjugă diferit în funcție de subiect. Cu toate acestea, restul propoziției nu este util pentru traducerea acestui cuvânt. În aceeași ordine de idei, la traducerea cuvântului „this”, modelul va trebui, de asemenea, să acorde atenție cuvântului „course”, deoarece „this” se traduce diferit în funcție de faptul dacă substantivul asociat este masculin sau feminin. Din nou, celelalte cuvinte din propoziție nu vor conta pentru traducerea cuvântului „course”. În cazul unor propoziții mai complexe (și al unor reguli gramaticale mai complexe), modelul ar trebui să acorde o atenție deosebită cuvintelor care ar putea apărea mai departe în propoziție pentru a traduce corect fiecare cuvânt. + +Același concept se aplică oricărei sarcini asociate cu limbajul natural: un cuvânt în sine are o semnificație, dar această semnificație este profund afectată de context, care poate fi orice alt cuvânt (sau cuvinte) înainte sau după cuvântul studiat. + +Acum, că aveți o idee despre ce sunt attention layers, să analizăm mai îndeaproape arhitectura Transformer. + +## Arhitectura originală[[arhitectura-originală] + +Arhitectura Transformer a fost concepută inițial pentru traducere. În timpul formării, codificatorul primește intrări (propoziții) într-o anumită limbă, în timp ce decodificatorul primește aceleași propoziții în limba țintă dorită. În codificator, attention layets pot utiliza toate cuvintele dintr-o propoziție (deoarece, după cum tocmai am văzut, traducerea unui anumit cuvânt poate depinde de ceea ce se află înainte și după el în propoziție). Cu toate acestea, decodificatorul funcționează secvențial și poate acorda atenție numai cuvintelor din propoziție pe care le-a tradus deja (deci, numai cuvintelor anterioare cuvântului generat în prezent). De exemplu, atunci când am prezis primele trei cuvinte din ținta tradusă, le dăm decodificatorului, care utilizează apoi toate intrările codificatorului pentru a încerca să prezică al patrulea cuvânt. + +Pentru a accelera lucrurile în timpul formării (atunci când modelul are acces la propozițiile țintă), decodorul primește întreaga țintă, dar nu i se permite să utilizeze cuvintele viitoare (dacă ar avea acces la cuvântul din poziția 2 atunci când încearcă să prezică cuvântul din poziția 2, problema nu ar fi foarte dificilă!) De exemplu, atunci când încearcă să prezică al patrulea cuvânt, stratul de atenție va avea acces doar la cuvintele de la pozițiile 1 și 3. + +Arhitectura originală a Transformer arăta astfel, cu codificatorul în stânga și decodificatorul în dreapta: + +
+Architecture of a Transformers models + +
+ +Rețineți că primul attention layer dintr-un bloc decodor acordă atenție tuturor intrărilor (trecute) către decodor, dar al doilea attention layer utilizează ieșirea codorului. Astfel, acesta poate accesa întreaga propoziție de intrare pentru a prezice cel mai bine cuvântul curent. Acest lucru este foarte util deoarece diferite limbi pot avea reguli gramaticale care pun cuvintele în ordine diferită sau un context furnizat mai târziu în propoziție poate fi util pentru a determina cea mai bună traducere a unui cuvânt dat. + +*attention mask* poate fi, de asemenea, utilizată în codificator/decodificator pentru a împiedica modelul să acorde atenție anumitor cuvinte speciale - de exemplu, cuvântul special de umplutură utilizat pentru a face ca toate intrările să aibă aceeași lungime atunci când se grupează propozițiile. + +## Architectura vs. punctele de control[[architectura-vs-punctele-de-control]] + +Pe măsură ce analizăm modelele Transformer în acest curs, veți vedea mențiuni despre *arhitecturi* și *puncte de control*, precum și despre *modele*. Toți acești termeni au semnificații ușor diferite: + +* **Arhitectură**: Acesta este scheletul modelului - definiția fiecărui strat și a fiecărei operațiuni care are loc în cadrul modelului. +* **Puncte de control**: Acestea sunt ponderile care vor fi încărcate într-o anumită arhitectură. +* **Model**: Acesta este un termen generic care nu este la fel de precis ca „arhitectură” sau „punct de control”: poate însemna ambele. Acest curs va specifica *arhitectură* sau *punct de control* atunci când este necesar pentru a reduce ambiguitatea. + +De exemplu, BERT este o arhitectură, în timp ce `bert-base-cased`, un set de ponderi antrenate de echipa Google pentru prima versiune a BERT, este un punct de control. Cu toate acestea, se poate spune „modelul BERT” și „modelul `bert-base-cased`”. \ No newline at end of file diff --git a/chapters/rum/chapter1/5.mdx b/chapters/rum/chapter1/5.mdx new file mode 100644 index 000000000..6a32cff0b --- /dev/null +++ b/chapters/rum/chapter1/5.mdx @@ -0,0 +1,22 @@ +# Modele Encoder[[modele-encoder]] + + + + + +Modelele Encoder utilizează doar encoderul unui model Transformer. La fiecare etapă, layer-urile de atenție pot accesa toate cuvintele din propoziția inițială. Aceste modele sunt adesea caracterizate ca având o atenție „bidirecțională” și sunt adesea numite *modele de autocodificare*. + +Preinstruirea acestor modele se bazează, de obicei, pe alterarea unei propoziții date (de exemplu, prin mascarea unor cuvinte aleatorii) și pe sarcina modelului de a găsi sau reconstrui propoziția inițială. + +Modelele Encoder sunt cele mai potrivite pentru sarcinile care necesită înțelegerea întregii propoziții, cum ar fi clasificarea propozițiilor, recunoașterea entităților numite (și, mai general, clasificarea cuvintelor) și Extractive QA. + +Printre reprezentanții acestei familii de modele se numără: + +- [ALBERT](https://huggingface.co/docs/transformers/model_doc/albert) +- [BERT](https://huggingface.co/docs/transformers/model_doc/bert) +- [DistilBERT](https://huggingface.co/docs/transformers/model_doc/distilbert) +- [ELECTRA](https://huggingface.co/docs/transformers/model_doc/electra) +- [RoBERTa](https://huggingface.co/docs/transformers/model_doc/roberta) diff --git a/chapters/rum/chapter1/6.mdx b/chapters/rum/chapter1/6.mdx new file mode 100644 index 000000000..9e284d5ea --- /dev/null +++ b/chapters/rum/chapter1/6.mdx @@ -0,0 +1,21 @@ +# Modele Decoder[[modele-decoder]] + + + + + +Modelele Decoder utilizează doar decodificatorul unui model Transformer. În fiecare etapă, pentru un cuvânt dat, layerele de atenție pot accesa doar cuvintele poziționate înaintea acestuia în propoziție. Aceste modele sunt adesea numite *modele autoregresive*. + +Preinstruirea modelelor de decodare se axează de obicei pe prezicerea următorului cuvânt din propoziție. + +Aceste modele sunt cele mai potrivite pentru sarcinile care implică generarea de text. + +Printre reprezentanții acestei familii de modele se numără: + +- [CTRL](https://huggingface.co/transformers/model_doc/ctrl) +- [GPT](https://huggingface.co/docs/transformers/model_doc/openai-gpt) +- [GPT-2](https://huggingface.co/transformers/model_doc/gpt2) +- [Transformer XL](https://huggingface.co/transformers/model_doc/transfo-xl) \ No newline at end of file diff --git a/chapters/rum/chapter1/7.mdx b/chapters/rum/chapter1/7.mdx new file mode 100644 index 000000000..8a93e0fd8 --- /dev/null +++ b/chapters/rum/chapter1/7.mdx @@ -0,0 +1,20 @@ +# Modele Sequence-to-sequence[modele-sequence-to-sequence] + + + + + +Modelele Encoder-Decoder (denumite și *modele sequence-to-sequence*) utilizează ambele părți ale arhitecturii Transformer. În fiecare etapă, layerele de atenție ale codificatorului pot accesa toate cuvintele din propoziția inițială, în timp ce layerele de atenție ale decodificatorului pot accesa doar cuvintele poziționate înaintea unui anumit cuvânt din intrare. + +Preinstruirea acestor modele se poate face folosind obiectivele modelelor de codificare sau de decodificare, dar de obicei implică ceva un pic mai complex. De exemplu, [T5](https://huggingface.co/t5-base) este preinstruit prin înlocuirea unor intervale aleatorii de text (care pot conține mai multe cuvinte) cu un singur cuvânt special mascat, iar obiectivul este apoi de a prezice textul pe care îl înlocuiește acest cuvânt mascat. + +Modelele Sequence-to-sequence sunt cele mai potrivite pentru sarcinile care se învârt în jurul generării de noi propoziții în funcție de o intrare dată, cum ar fi rezumarea, traducerea sau răspunsul generativ la întrebări. + +Printre reprezentanții acestei familii de modele se numără: +- [BART](https://huggingface.co/transformers/model_doc/bart) +- [mBART](https://huggingface.co/transformers/model_doc/mbart) +- [Marian](https://huggingface.co/transformers/model_doc/marian) +- [T5](https://huggingface.co/transformers/model_doc/t5) diff --git a/chapters/rum/chapter1/8.mdx b/chapters/rum/chapter1/8.mdx new file mode 100644 index 000000000..5f6049d2a --- /dev/null +++ b/chapters/rum/chapter1/8.mdx @@ -0,0 +1,31 @@ +# Prejudecăți și limitări[[prejudecăți-și-limitări]] + + + +În cazul în care intenționați să utilizați un model preinstruit sau o versiune ajustată în producție, vă rugăm să fiți conștienți de faptul că, deși aceste modele sunt instrumente puternice, ele au anumite limitări. Cea mai importantă dintre acestea este că, pentru a permite preinstruirea pe cantități mari de date, cercetătorii deseori extrag tot conținutul pe care îl pot găsi, luând atât ce este mai bun, cât și ce este mai rău din ceea ce este disponibil pe internet. + +Pentru a oferi o ilustrare rapidă, să ne întoarcem la exemplul unui pipeline `fill-mask` cu modelul BERT: +```python +from transformers import pipeline + +unmasker = pipeline("fill-mask", model="bert-base-uncased") +result = unmasker("This man works as a [MASK].") +print([r["token_str"] for r in result]) + +result = unmasker("This woman works as a [MASK].") +print([r["token_str"] for r in result]) +``` + +```python out +['lawyer', 'carpenter', 'doctor', 'waiter', 'mechanic'] +['nurse', 'waitress', 'teacher', 'maid', 'prostitute'] +``` + +Atunci când i se cere să completeze cuvântul care lipsește din aceste două propoziții, modelul dă un singur răspuns fără gen (chelner/ chelneriță). Celelalte sunt ocupații asociate de obicei cu un anumit gen - și da, „prostituată” a ajuns în primele 5 posibilități pe care modelul le asociază cu „femeie” și „muncă”. Acest lucru se întâmplă chiar dacă BERT este unul dintre puținele modele Transformer care nu este construit prin extragerea de date de pe întregul internet, ci mai degrabă folosind date aparent neutre (este antrenat pe seturile de date [English Wikipedia](https://huggingface.co/datasets/wikipedia) și [BookCorpus](https://huggingface.co/datasets/bookcorpus)). + +Prin urmare, atunci când utilizați aceste instrumente, trebuie să aveți în minte faptul că modelul original pe care îl utilizați ar putea genera foarte ușor conținut sexist, rasist sau homofob. Reglarea fină a modelului pe baza datelor dumneavoastră nu va face ca această prejudecată intrinsecă să dispară. \ No newline at end of file diff --git a/chapters/rum/chapter1/9.mdx b/chapters/rum/chapter1/9.mdx new file mode 100644 index 000000000..4d0cd5a4a --- /dev/null +++ b/chapters/rum/chapter1/9.mdx @@ -0,0 +1,16 @@ +# Sumar[[sumar]] + + + +În acest capitol, ați văzut cum să abordați diferite sarcini NLP utilizând funcția de nivel înalt `pipeline()` din 🤗 Transformers. De asemenea, ați văzut cum să căutați și să utilizați modele în Hub, precum și cum să utilizați API-ul de inferență pentru a testa modelele direct în browser. + +Am discutat despre modul în care funcționează modelele Transformer la un nivel general și am vorbit despre importanța învățării prin transfer și a reglării fine. Un aspect cheie este faptul că puteți utiliza întreaga arhitectură sau doar codificatorul sau decodificatorul, în funcție de tipul de sarcină pe care doriți să o rezolvați. Următorul tabel rezumă acest aspect: + +| Model | Exemple | Task-uri | +|-----------------|--------------------------------------------|----------------------------------------------------------------------------------| +| Encoder | ALBERT, BERT, DistilBERT, ELECTRA, RoBERTa | Clasificarea propozițiilor, recunoașterea entităților denumite, Extractive QA | +| Decoder | CTRL, GPT, GPT-2, Transformer XL | Generarea de text | +| Encoder-decoder | BART, T5, Marian, mBART | Rezumare, traducere, răspunsuri generative la întrebări | From bc49d4d5835e7c9b2c25305cb16497a1cd3d9052 Mon Sep 17 00:00:00 2001 From: "ludmila.friptu" Date: Sun, 20 Oct 2024 20:41:21 +0300 Subject: [PATCH 004/167] Add chapter 2 without the translation of the quiz --- chapters/rum/chapter2/1.mdx | 28 +++ chapters/rum/chapter2/2.mdx | 364 ++++++++++++++++++++++++++++++++++++ chapters/rum/chapter2/3.mdx | 235 +++++++++++++++++++++++ chapters/rum/chapter2/4.mdx | 246 ++++++++++++++++++++++++ chapters/rum/chapter2/5.mdx | 338 +++++++++++++++++++++++++++++++++ chapters/rum/chapter2/6.mdx | 164 ++++++++++++++++ chapters/rum/chapter2/7.mdx | 19 ++ chapters/rum/chapter2/8.mdx | 310 ++++++++++++++++++++++++++++++ 8 files changed, 1704 insertions(+) create mode 100644 chapters/rum/chapter2/1.mdx create mode 100644 chapters/rum/chapter2/2.mdx create mode 100644 chapters/rum/chapter2/3.mdx create mode 100644 chapters/rum/chapter2/4.mdx create mode 100644 chapters/rum/chapter2/5.mdx create mode 100644 chapters/rum/chapter2/6.mdx create mode 100644 chapters/rum/chapter2/7.mdx create mode 100644 chapters/rum/chapter2/8.mdx diff --git a/chapters/rum/chapter2/1.mdx b/chapters/rum/chapter2/1.mdx new file mode 100644 index 000000000..75093a9f9 --- /dev/null +++ b/chapters/rum/chapter2/1.mdx @@ -0,0 +1,28 @@ +# Introducere[[introducere]] + + + +După cum ați văzut în [Capitolul 1](/course/chapter1), modelele Transformer sunt de obicei foarte voluminoase. Fiind alcătuite din milioane până la zeci de *miliarde* de parametri, instruirea și implementarea acestor modele este o sarcină complicată. În plus, cu noi modele lansate aproape zilnic și fiecare având propria sa implementare, testarea tuturor acestora nu este o sarcină ușoară. + +Biblioteca 🤗 Transformers a fost creată pentru a rezolva această problemă. Scopul său este de a oferi un singur API prin care orice model Transformer poate fi încărcat, instruit și salvat. Principalele caracteristici ale bibliotecii sunt: + +- ** Simplitate în utilizare**: Descărcarea, încărcarea și utilizarea unui model NLP de ultimă generație pentru inferență pot fi realizate în doar două linii de cod. +- **Flexibilitate**: În esența lor, toate modelele sunt simple clase PyTorch `nn.Module` sau TensorFlow `tf.keras.Model` și pot fi manipulate ca orice alte modele în framework-urile lor respective de învățare automată (ML). +- **Simplitate**: Aproape că nu se fac abstractizări în întreaga bibliotecă. „All in one file” este un concept de bază: trecerea înainte a unui model este definită în întregime într-un singur fișier, astfel încât codul în sine să fie ușor de înțeles și hackable. + +Această ultimă caracteristică face 🤗 Transformers destul de diferit de alte biblioteci ML. Modelele nu sunt construite pe module +care sunt partajate între fișiere; în schimb, fiecare model are propriile sale straturi. În plus, pe lângă faptul că modelele sunt mai ușor de abordat și de înțeles, acest lucru vă permite să experimentați cu ușurință pe un model fără a le afecta pe celelalte. + +Acest capitol va începe cu un exemplu end-to-end în care folosim împreună un model și un tokenizer pentru a replica funcția `pipeline()` introdusă în [Capitolul 1](/course/chapter1). În continuare, vom discuta despre API-ul modelului: vom analiza clasele de model și de configurare și vă vom arăta cum să încărcați un model și cum acesta procesează intrările numerice pentru a genera predicții. + +Apoi vom analiza API-ul tokenizer, care este cealaltă componentă principală a funcției `pipeline()`. Tokenizerii se ocupă de prima și ultima etapă de procesare, gestionând conversia de la text la intrări numerice pentru rețeaua neuronală și conversia înapoi la text atunci când este necesar. În cele din urmă, vă vom arăta cum să vă ocupați de trimiterea mai multor propoziții printr-un model în cadrul unui lot pregătit, apoi vom încheia totul cu o examinare mai atentă a funcției `tokenizer()`. + + + +⚠️ +Pentru a beneficia de toate funcțiile disponibile cu Model Hub și 🤗 Transformers, vă recomandăm să vă creați un cont. + + \ No newline at end of file diff --git a/chapters/rum/chapter2/2.mdx b/chapters/rum/chapter2/2.mdx new file mode 100644 index 000000000..b0f1c4855 --- /dev/null +++ b/chapters/rum/chapter2/2.mdx @@ -0,0 +1,364 @@ + + +# În spatele pipeline-ului[[în-spatele-pipeline-ului]] + +{#if fw === 'pt'} + + + +{:else} + + + +{/if} + + + +Aceasta este prima secțiune în care conținutul este ușor diferit în funcție de utilizarea PyTorch sau TensorFlow. Schimbați comutatorul din partea de sus a titlului pentru a selecta platforma pe care o preferați! + + +{#if fw === 'pt'} + +{:else} + +{/if} + +Să începem cu un exemplu complet, aruncând o privire la ceea ce s-a întâmplat în spate atunci când am executat următorul cod în [Capitolul 1](/curs/capitol1): + + +```python +from transformers import pipeline + +classifier = pipeline("sentiment-analysis") +classifier( + [ + "I've been waiting for a HuggingFace course my whole life.", + "I hate this so much!", + ] +) +``` + +și am obținut: + +```python out +[{'label': 'POSITIVE', 'score': 0.9598047137260437}, + {'label': 'NEGATIVE', 'score': 0.9994558095932007}] +``` + +După cum am văzut în [Capitolul 1](/course/chapter1), acest pipeline grupează trei etape: preprocesarea, trecerea intrărilor prin model și postprocesarea: + +
+The full NLP pipeline: tokenization of text, conversion to IDs, and inference through the Transformer model and the model head. + +
+ +Să trecem rapid prin fiecare dintre acestea. + +## Preprocesarea cu un tokenizator[[preprocesarea-cu-un-tokenizerator]] + +La fel ca alte rețele neuronale, modelele Transformer nu pot procesa direct text brut, astfel încât primul pas al pipeline-ului nostru este de a converti intrările de text în numere pe care modelul le poate înțelege. Pentru a face acest lucru, folosim un *tokenizer*, care va fi responsabil pentru: + +- Împărțirea datelor de intrare în cuvinte, părți de cuvinte sau simboluri (cum ar fi punctuația) care se numesc *tokens* +- Maparea fiecărui token într-un număr întreg +- Adăugarea de intrări suplimentare care pot fi utile pentru model + +Toată această preprocesare trebuie efectuată exact în același mod ca atunci când modelul a fost preinstruit, așa că mai întâi trebuie să descărcăm aceste informații din [Model Hub] (https://huggingface.co/models). Pentru a face acest lucru, folosim clasa `AutoTokenizer` și metoda sa `from_pretrained()`. Folosind numele checkpoint-ului modelului nostru, aceasta va prelua automat datele asociate cu tokenizer-ul modelului și le va stoca în cache (astfel încât acestea să fie descărcate doar prima dată când executați codul de mai jos). + +Deoarece punctul de control implicit al pipeline-ului `sentiment-analysis` este `distilbert-base-uncased-finetuned-sst-2-english` (puteți vedea fișa modelului [aici](https://huggingface.co/distilbert-base-uncased-finetuned-sst-2-english)), executăm următoarele: + +```python +from transformers import AutoTokenizer + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) +``` + +Odată ce avem tokenizatorul, putem să îi transmitem direct propozițiile noastre și vom primi înapoi un dicționar care este gata să fie introdus în modelul nostru! Singurul lucru rămas de făcut este să convertim lista de ID-uri de intrare în tensori. + +Puteți utiliza 🤗 Transformers fără a trebui să vă faceți griji cu privire la cadrul ML utilizat ca backend; ar putea fi PyTorch sau TensorFlow, sau Flax pentru unele modele. Cu toate acestea, modelele Transformer acceptă numai *tensori * ca intrare. Dacă este prima dată când auziți despre tensori, vă puteți gândi la ei ca la matrici NumPy. Un array NumPy poate fi un scalar (0D), un vector (1D), o matrice (2D) sau poate avea mai multe dimensiuni. Este de fapt un tensor; tensorii altor cadre ML se comportă similar și sunt de obicei la fel de simplu de instanțiat ca și array-urile NumPy. + +Pentru a specifica tipul de tensori pe care dorim să îi primim înapoi (PyTorch, TensorFlow sau NumPy simplu), folosim argumentul `return_tensors`: + + +{#if fw === 'pt'} +```python +raw_inputs = [ + "I've been waiting for a HuggingFace course my whole life.", + "I hate this so much!", +] +inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt") +print(inputs) +``` +{:else} +```python +raw_inputs = [ + "I've been waiting for a HuggingFace course my whole life.", + "I hate this so much!", +] +inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="tf") +print(inputs) +``` +{/if} + + +Nu vă faceți încă griji cu privire la padding și trunchiere; le vom explica mai târziu. Principalele lucruri de reținut aici sunt că puteți trece o propoziție sau o listă de propoziții, precum și specificarea tipului de tensori pe care doriți să îi primiți înapoi (dacă nu este trecut niciun tip, veți primi o listă de liste ca rezultat) +{#if fw === 'pt'} + +Iată cum arată rezultatele ca tensori PyTorch: + +```python out +{ + 'input_ids': tensor([ + [ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102], + [ 101, 1045, 5223, 2023, 2061, 2172, 999, 102, 0, 0, 0, 0, 0, 0, 0, 0] + ]), + 'attention_mask': tensor([ + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0] + ]) +} +``` +{:else} + +Iată cum arată rezultatele ca tensori TensorFlow: + +```python out +{ + 'input_ids': , + 'attention_mask': +} +``` +{/if} + + +Rezultatul în sine este un dicționar care conține două chei, `input_ids` și `attention_mask`. `input_ids` conține două rânduri de numere întregi (unul pentru fiecare propoziție) care sunt identificatorii unici ai simbolurilor din fiecare propoziție. Vom explica ce este `attention_mask` mai târziu în acest capitol. + +## Parcurgerea modelului[[parcurgerea-modelului]] + +{#if fw === 'pt'} +Putem descărca modelul nostru preinstruit în același mod în care am făcut-o cu tokenizatorul nostru. 🤗 Transformers oferă o clasă `AutoModel` care are și o metodă `from_pretrained()`: + +```python +from transformers import AutoModel + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +model = AutoModel.from_pretrained(checkpoint) +``` +{:else} + +Putem descărca modelul nostru preinstruit în același mod în care am făcut-o cu tokenizatorul nostru. 🤗 Transformers oferă o clasă `TFAutoModel` care are și o metodă `from_pretrained`: + +```python +from transformers import TFAutoModel + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +model = TFAutoModel.from_pretrained(checkpoint) +``` +{/if} + + +În acest fragment de cod, am descărcat același checkpoint pe care l-am folosit anterior în pipeline-ul nostru (de fapt, ar fi trebuit să fie deja în cache) și am instanțiat un model cu acesta. + +Această arhitectură conține doar modulul Transformer de bază: având în vedere anumite intrări, acesta produce ceea ce vom numi *stări ascunse*, cunoscute și ca *caracteristici*. Pentru fiecare intrare a modelului, vom extrage un vector înalt-dimensional care reprezintă **înțelegerea contextuală a intrării respective de către modelul Transformer**. + +Dacă acest lucru nu are sens, nu vă faceți griji. Vom explica totul mai târziu. + +Deși aceste stări ascunse pot fi utile pe cont propriu, ele sunt de obicei intrări pentru o altă parte a modelului, cunoscută sub numele de *head*. În [Capitolul 1](/curs/capitol1), diferitele sarcini ar fi putut fi efectuate cu aceeași arhitectură, dar fiecăreia dintre aceste sarcini îi va fi asociat un head diferit. + +### Un vector multidimensional?[[un-vector-multidimensional]] + + +Vectorul emis de modulul Transformator este de obicei de dimensiuni mari. Acesta are în general trei dimensiuni: + +- **Dimensiunea lotului**: Numărul de secvențe prelucrate simultan (2 în exemplul nostru). +- **Lungimea secvenței**: Lungimea reprezentării numerice a secvenței (16 în exemplul nostru). +- **Dimensiunea ascunsă**: Dimensiunea vectorială a fiecărei intrări a modelului. + +Se spune că este multidimensional din cauza ultimei valori. Dimensiunea ascunsă poate fi foarte mare (768 este comună pentru modelele mai mici, iar în modelele mai mari aceasta poate ajunge la 3072 sau mai mult). + +Putem vedea acest lucru dacă introducem în modelul nostru intrările pe care le-am preprocesat: + +{#if fw === 'pt'} +```python +outputs = model(**inputs) +print(outputs.last_hidden_state.shape) +``` + +```python out +torch.Size([2, 16, 768]) +``` +{:else} +```py +outputs = model(inputs) +print(outputs.last_hidden_state.shape) +``` + +```python out +(2, 16, 768) +``` +{/if} + + +Rețineți că ieșirile modelelor 🤗 Transformers se comportă ca `namedtuple`s sau dicționare. Puteți accesa elementele prin atribute (așa cum am făcut noi) sau prin cheie (`outputs[„last_hidden_state”]`), sau chiar prin index dacă știți exact unde se află lucrul pe care îl căutați (`outputs[0]`). + +### Modele de head-uri: Înțelegerea numerelor[modele-de-head-uri-înțelegerea-numerelor]] + +Head-urile modelelor iau ca intrare vectorul multidimensional al stărilor ascunse și le proiectează pe o altă dimensiune. Acestea sunt de obicei compuse din unul sau câteva straturi liniare: + +
+A Transformer network alongside its head. + +
+ + +Rezultatul modelului Transformer este trimis direct la head-ul modelului pentru a fi prelucrat. + +În această diagramă, modelul este reprezentat de stratul său de încorporare și de straturile următoare. Stratul de încorporare convertește fiecare ID de intrare din intrarea tokenizată într-un vector care reprezintă tokenul asociat. Straturile ulterioare manipulează acești vectori folosind mecanismul de atenție pentru a produce reprezentarea finală a propozițiilor. + +Există multe arhitecturi diferite disponibile în 🤗 Transformers, fiecare fiind concepută în jurul abordării unei sarcini specifice. Iată o listă neexhaustivă: + +- `*Model` (extragerea stărilor ascunse) +- `*ForCausalLM` +- `*ForMaskedLM` +- `*ForMultipleChoice` +- `*ForQuestionAnswering` +- `*ForSequenceClassification` +- `*ForTokenClassification` +- și altele 🤗 + +{#if fw === 'pt'} + Pentru exemplul nostru, vom avea nevoie de un model cu un head de clasificare a secvențelor (pentru a putea clasifica propozițiile ca fiind pozitive sau negative). Așadar, nu vom utiliza clasa `AutoModel`, ci `AutoModelForSequenceClassification`: + +```python +from transformers import AutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +model = AutoModelForSequenceClassification.from_pretrained(checkpoint) +outputs = model(**inputs) +``` +{:else} + Pentru exemplul nostru, vom avea nevoie de un model cu un head de clasificare a secvențelor (pentru a putea clasifica propozițiile ca fiind pozitive sau negative). Așadar, nu vom utiliza clasa `TFAutoModel`, ci `TFAutoModelForSequenceClassification`: + +```python +from transformers import TFAutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint) +outputs = model(inputs) +``` +{/if} + +Acum, dacă ne uităm la forma ieșirilor noastre, dimensiunea va fi mult mai mică: head-ul modelului ia ca intrare vectorii multidimensionali pe care i-am văzut înainte și scoate vectori care conțin două valori (una pentru fiecare etichetă): + +```python +print(outputs.logits.shape) +``` + +{#if fw === 'pt'} +```python out +torch.Size([2, 2]) +``` +{:else} +```python out +(2, 2) +``` +{/if} + + +Deoarece avem doar două propoziții și două etichete, rezultatul pe care îl obținem din modelul nostru este de forma 2 x 2. + +## Postprocesarea rezultatului[[postprocesarea-rezultatului]] + +Valorile pe care le obținem ca rezultat al modelului nostru nu au neapărat sens în sine. Să aruncăm o privire: + +```python +print(outputs.logits) +``` + +{#if fw === 'pt'} +```python out +tensor([[-1.5607, 1.6123], + [ 4.1692, -3.3464]], grad_fn=) +``` +{:else} +```python out + +``` +{/if} + +Modelul nostru a prezis `[-1.5607, 1.6123]` pentru prima propoziție și `[ 4.1692, -3.3464]` pentru cea de-a doua. Acestea nu sunt probabilități, ci *logits*, scorurile brute, nenormalizate, emise de ultimul strat al modelului. Pentru a fi convertite în probabilități, acestea trebuie să treacă printr-un strat [SoftMax](https://en.wikipedia.org/wiki/Softmax_function) (toate modelele 🤗 Transformers produc logits, deoarece funcția de pierdere pentru formare va fuziona în general ultima funcție de activare, cum ar fi SoftMax, cu funcția de pierdere reală, cum ar fi entropia încrucișată): + +{#if fw === 'pt'} +```py +import torch + +predictions = torch.nn.functional.softmax(outputs.logits, dim=-1) +print(predictions) +``` +{:else} +```py +import tensorflow as tf + +predictions = tf.math.softmax(outputs.logits, axis=-1) +print(predictions) +``` +{/if} + +{#if fw === 'pt'} +```python out +tensor([[4.0195e-02, 9.5980e-01], + [9.9946e-01, 5.4418e-04]], grad_fn=) +``` +{:else} +```python out +tf.Tensor( +[[4.01951671e-02 9.59804833e-01] + [9.9945587e-01 5.4418424e-04]], shape=(2, 2), dtype=float32) +``` +{/if} + + +Acum putem vedea că modelul a prezis `[0.0402, 0.9598]` pentru prima propoziție și `[0.9995, 0.0005]` pentru cea de-a doua. Acestea sunt scoruri de probabilitate care pot fi recunoscute. + +Pentru a obține etichetele corespunzătoare fiecărei poziții, putem inspecta atributul `id2label` din configurația modelului (mai multe despre acest lucru în secțiunea următoare): + +```python +model.config.id2label +``` + +```python out +{0: 'NEGATIVE', 1: 'POSITIVE'} +``` +Acum putem concluziona că modelul a prezis următoarele: + +- Prima propoziție: NEGATIV: 0,0402, POZITIV: 0,9598 +- A doua propoziție: NEGATIVĂ: 0,9995, POZITIVĂ: 0,0005 + +Am reprodus cu succes cele trei etape ale pipeline-ului: preprocesarea cu tokenizere, trecerea intrărilor prin model și postprocesarea! Acum haideți să analizăm în profunzime fiecare dintre aceste etape. + + + +✏️ +** Încercați!** Alegeți două (sau mai multe) texte proprii și treceți-le prin conducta `sentiment-analysis`. Apoi repetați pașii pe care i-ați văzut aici și verificați dacă obțineți aceleași rezultate! + + diff --git a/chapters/rum/chapter2/3.mdx b/chapters/rum/chapter2/3.mdx new file mode 100644 index 000000000..e0f0758df --- /dev/null +++ b/chapters/rum/chapter2/3.mdx @@ -0,0 +1,235 @@ + + +# Modele[[modele]] + +{#if fw === 'pt'} + + + +{:else} + + + +{/if} + +{#if fw === 'pt'} + +{:else} + +{/if} + +{#if fw === 'pt'} + +În această secțiune vom analiza mai detaliat crearea și utilizarea unui model. Vom folosi clasa `AutoModel`, care este utilă atunci când doriți să instanțiați orice model dintr-un checkpoint. + +Clasa `AutoModel` și toate celelalte clase înrudite sunt, de fapt, simple wrappere ale gamei largi de modele disponibile în bibliotecă. Este un wrapper inteligent, deoarece poate ghici automat arhitectura modelului corespunzător pentru checkpoint-ul dumneavoastră și apoi instanțiază un model cu această arhitectură. + +{:else} + +În această secțiune vom analiza mai detaliat crearea și utilizarea unui model. Vom utiliza clasa `TFAutoModel`, care este utilă atunci când doriți să instanțați un model dintr-un checkpoint. + +Clasa `TFAutoModel` și toate clasele înrudite cu aceasta sunt de fapt simple wrappere ale gamei largi de modele disponibile în bibliotecă. Este un wrapper inteligent, deoarece poate ghici automat arhitectura modelului corespunzător pentru checkpoint-ul dumneavoastră și apoi instanțiază un model cu această arhitectură. + +{/if} + +Cu toate acestea, dacă știți ce tip de model doriți să utilizați, puteți folosi direct clasa care definește arhitectura acestuia. Să aruncăm o privire la modul în care funcționează acest lucru cu un model BERT. + +## Crearea unui Transformer[[crearea-unui-transformer]] + +Primul lucru pe care va trebui să îl facem pentru a inițializa un model BERT este să încărcăm un obiect de configurare: + +{#if fw === 'pt'} +```py +from transformers import BertConfig, BertModel + +# Construirea configurației +config = BertConfig() + +# Construirea modelului pornind de la configurație +model = BertModel(config) +``` +{:else} +```py +from transformers import BertConfig, TFBertModel + +# Construirea configurației +config = BertConfig() + +# Construirea modelului pornind de la configurație +model = TFBertModel(config) +``` +{/if} + +Configurația conține multe atribute care sunt utilizate pentru a construi modelul: + +```py +print(config) +``` + +```python out +BertConfig { + [...] + "hidden_size": 768, + "intermediate_size": 3072, + "max_position_embeddings": 512, + "num_attention_heads": 12, + "num_hidden_layers": 12, + [...] +} +``` + +Deși nu ați văzut încă ce fac toate aceste atribute, ar trebui să recunoașteți unele dintre ele: atributul `hidden_size` definește dimensiunea vectorului `hidden_states`, iar `num_hidden_layers` definește numărul de straturi pe care le are modelul Transformer. + +### Diferite metode de încărcare[[diferite-metode-de-încărcare]] + +Crearea unui model din configurația implicită îl inițializează cu valori aleatorii: + + +{#if fw === 'pt'} +```py +from transformers import BertConfig, BertModel + +config = BertConfig() +model = BertModel(config) + +# Modelul este inițializat aleatoriu! +``` +{:else} +```py +from transformers import BertConfig, TFBertModel + +config = BertConfig() +model = TFBertModel(config) + +# Modelul este inițializat aleatoriu! +``` +{/if} + +Modelul poate fi utilizat în această stare, dar va produce rezultate neclare; mai întâi trebuie să fie antrenat. Am putea antrena modelul de la zero pentru sarcina în cauză, dar, după cum ați văzut în [Capitolul 1](/course/chapter1), acest lucru ar necesita mult timp și o mulțime de date și ar avea un impact semnificativ asupra mediului. Pentru a evita efortul inutil, este esențial să puteți partaja și reutiliza modelele care au fost deja formate. + +Încărcarea unui model Transformer care este deja instruit este simplă - putem face acest lucru utilizând metoda `from_pr + +{#if fw === 'pt'} +```py +from transformers import BertModel + +model = BertModel.from_pretrained("bert-base-cased") +``` + +După cum ați văzut mai devreme, am putea înlocui `BertModel` cu clasa `AutoModel` echivalentă. Vom face acest lucru în continuare, deoarece acest lucru produce un cod compatibil cu checkpoint-urile; dacă codul dumneavoastră funcționează pentru un checkpoint, ar trebui să funcționeze fără probleme pentru altul. Acest lucru este valabil chiar dacă arhitectura este diferită, atât timp cât checkpoint-ul a fost instruit pentru o sarcină similară (de exemplu, o sarcină de analiză a sentimentelor). + +{:else} +```py +from transformers import TFBertModel + +model = TFBertModel.from_pretrained("bert-base-cased") +``` + +După cum ați văzut mai devreme, am putea înlocui `BertModel` cu clasa `AutoModel` echivalentă. Vom face acest lucru în continuare, deoarece acest lucru produce un cod compatibil cu checkpoint-urile; dacă codul dumneavoastră funcționează pentru un checkpoint, ar trebui să funcționeze fără probleme pentru altul. Acest lucru este valabil chiar dacă arhitectura este diferită, atât timp cât checkpoint-ul a fost instruit pentru o sarcină similară (de exemplu, o sarcină de analiză a sentimentelor). + +{/if} + +În exemplul de cod de mai sus nu am utilizat `BertConfig` și, în loc de acesta, am încărcat un model preinstruit prin intermediul identificatorului `bert-base-cased`. Acesta este un checkpoint al modelului care a fost antrenat chiar de autorii BERT; puteți găsi mai multe detalii despre acesta în [model card](https://huggingface.co/bert-base-cased). + +Acest model este acum inițializat cu toate weight-urile din checkpoint. Acesta poate fi utilizat direct pentru inferență pe sarcinile pe care a fost antrenat și poate fi, de asemenea, ajustat pe o sarcină nouă. Prin antrenarea cu weight-uri instruite în prealabil, putem obține rapid rezultate bune. + +Greutățile au fost descărcate și stocate în cache (astfel încât apelurile viitoare la metoda `from_pretrained()` nu le vor descărca din nou) în folderul cache, care are ca valoare implicită *~/.cache/huggingface/transformers*. Puteți personaliza folderul cache prin setarea variabilei de mediu `HF_HOME`. + +Identificatorul utilizat pentru încărcarea modelului poate fi identificatorul oricărui model de pe Model Hub, atâta timp cât acesta este compatibil cu arhitectura OARET. Lista completă a checkpoint-urilor OARET disponibile poate fi găsită [aici](https://huggingface.co/models?filter=bert). + + +### Metode de păstrare[[metode-de-păstrare]] + +Salvarea unui model este la fel de ușoară ca încărcarea unuia - folosim metoda `save_pretrained()`, care este analogă metodei `from_pretrained()`: + +```py +model.save_pretrained("directory_on_my_computer") +``` + +Se salvează două fișiere pe disc: + +{#if fw === 'pt'} +``` +ls directory_on_my_computer + +config.json pytorch_model.bin +``` +{:else} +``` +ls directory_on_my_computer + +config.json tf_model.h5 +``` +{/if} + +Dacă aruncați o privire la fișierul *config.json*, veți recunoaște atributele necesare pentru construirea arhitecturii modelului. Acest fișier conține, de asemenea, unele metadate, cum ar fi locul de origine al checkpoint-ului și ce versiune 🤗 Transformers ați folosit când ați salvat ultima dată checkpoint-ul. + +{#if fw === 'pt'} + +Fișierul *pytorch_model.bin* este cunoscut sub numele de *state dictionary*; acesta conține toate weight-urile modelului dumneavoastră. Cele două fișiere merg mână în mână; configurația este necesară pentru a cunoaște arhitectura modelului, în timp ce weight-urile modelului sunt parametrii modelului. + +{:else} + +Fișierul *tf_model.h5* este cunoscut sub numele de *state dictionary*; acesta conține toate weight-urile modelului dumneavoastră. Cele două fișiere merg mână în mână; configurația este necesară pentru a cunoaște arhitectura modelului, în timp ce weight-urile modelului sunt parametrii modelului. + +{/if} + +## Utilizarea unui model Transformer pentru inferență[[utilizarea-unui-model-transformer-pentru-inferență]] + + +Acum că știți cum să încărcați și să salvați un model, să încercăm să îl folosim pentru a face câteva predicții. Modelele Transformer pot procesa doar numere - numere pe care le generează tokenizatorul. Dar înainte de a discuta despre tokenizeri, să explorăm ce intrări acceptă modelul. + +Tokenizerii se pot ocupa de transformarea intrărilor în tensori ai framework-ului corespunzător, dar pentru a vă ajuta să înțelegeți ce se întâmplă, vom arunca o privire rapidă la ceea ce trebuie făcut înainte de trimiterea intrărilor către model. + +Să spunem că avem câteva secvențe: + +```py +sequences = ["Hello!", "Cool.", "Nice!"] +``` + +Tokenizatorul le convertește în indici de vocabular care sunt denumiți în mod obișnuit *input IDs*. Fiecare secvență este acum o listă de numere! Rezultatul este: + +```py no-format +encoded_sequences = [ + [101, 7592, 999, 102], + [101, 4658, 1012, 102], + [101, 3835, 999, 102], +] +``` + +Aceasta este o listă de secvențe codificate: o listă de liste. Tensorii acceptă numai forme dreptunghiulare (gândiți-vă la matrici). Această " listă " are deja o formă dreptunghiulară, astfel încât convertirea sa într-un tensor este ușoară: + +{#if fw === 'pt'} +```py +import torch + +model_inputs = torch.tensor(encoded_sequences) +``` +{:else} +```py +import tensorflow as tf + +model_inputs = tf.constant(encoded_sequences) +``` +{/if} + +### Utilizarea tensorilor ca intrări în model[[utilizarea-tensorilor-ca-intrări-în-to-model]] + +Utilizarea tensorilor cu ajutorul modelului este extrem de simplă - trebuie doar să apelăm modelul cu intrările: + +```py +output = model(model_inputs) +``` + +Deși modelul acceptă o mulțime de argumente diferite, doar ID-urile de intrare sunt necesare. Vom explica mai târziu ce fac celelalte argumente și când sunt necesare, +dar mai întâi trebuie să aruncăm o privire mai atentă la tokenizerii care construiesc intrările pe care un model Transformer le poate înțelege. \ No newline at end of file diff --git a/chapters/rum/chapter2/4.mdx b/chapters/rum/chapter2/4.mdx new file mode 100644 index 000000000..c38234e14 --- /dev/null +++ b/chapters/rum/chapter2/4.mdx @@ -0,0 +1,246 @@ + + +# Tokenizere[[tokenizere]] + +{#if fw === 'pt'} + + + +{:else} + + + +{/if} + + + + +Tokenizoarele sunt una dintre componentele de bază ale pipeline-ului NLP. Acestea au un singur scop: să transforme textul în date care pot fi prelucrate de model. Modelele pot procesa doar numere, astfel încât tokenizerii trebuie să convertească intrările noastre de text în date numerice. În această secțiune, vom explora exact ce se întâmplă în pipeline-ul de tokenizare. + +În sarcinile NLP, datele care sunt în general prelucrate sunt text brut. Iată un exemplu de astfel de text: + +``` +Jim Henson was a puppeteer + +``` + +Cu toate acestea, modelele pot procesa doar numere, deci trebuie să găsim o modalitate de a converti textul brut în numere. Asta fac tokenizerii și există o mulțime de modalități de a face acest lucru. Scopul este de a găsi cea mai relevantă reprezentare - adică cea care are cel mai mare sens pentru model - și, dacă este posibil, cea mai mică reprezentare. + +Să aruncăm o privire la câteva exemple de algoritmi de tokenizare și să încercăm să răspundem la unele dintre întrebările pe care le puteți avea despre tokenizare. + + + +## Word-based[[word-based]] + + + + +Primul tip de tokenizator care îmi vine în minte este _word-based_. În general, este foarte ușor de configurat și de utilizat, cu doar câteva reguli, și adesea produce rezultate satisfăcătoare. De exemplu, în imaginea de mai jos, obiectivul este de a împărți textul brut în cuvinte și de a găsi o reprezentare numerică pentru fiecare dintre ele: + +
+ An example of word-based tokenization. + +
+ + +Există diferite moduri de a împărți textul. De exemplu, am putea folosi spațiu pentru a tokeniza textul în cuvinte prin aplicarea funcției `split()` din Python: + + +```py +tokenized_text = "Jim Henson was a puppeteer".split() +print(tokenized_text) +``` + +```python out +['Jim', 'Henson', 'was', 'a', 'puppeteer'] +``` + +Există, de asemenea, variații ale tokenizerelor de cuvinte care au reguli suplimentare pentru punctuație. Cu acest tip de tokenizator, putem ajunge la „vocabulare” destul de mari, unde un vocabular este definit de numărul total de token-uri independente pe care le avem în corpus. + +Fiecărui cuvânt i se atribuie un ID, începând de la 0 și mergând până la dimensiunea vocabularului. Modelul utilizează aceste ID-uri pentru a identifica fiecare cuvânt. + +Dacă dorim să acoperim complet o limbă cu un tokenizer bazat pe cuvinte, va trebui să avem un identificator pentru fiecare cuvânt din limbă, ceea ce va genera o cantitate uriașă de token-uri. De exemplu, există peste 500 000 de cuvinte în limba engleză, astfel încât, pentru a construi o hartă de la fiecare cuvânt la un ID de intrare, ar trebui să ținem evidența unui număr atât de mare de ID-uri. În plus, cuvinte precum „dog” sunt reprezentate diferit de cuvinte precum „dogs”, iar modelul nu va avea inițial nicio modalitate de a ști că „dog” și „dogs” sunt similare: va identifica cele două cuvinte ca neavând legătură. Același lucru este valabil și pentru alte cuvinte similare, precum „run” și „running”, pe care modelul nu le va vedea inițial ca fiind similare. + +În cele din urmă, avem nevoie de un token personalizat pentru a reprezenta cuvintele care nu se află în vocabularul nostru. Acesta este cunoscut sub numele de token "necunoscut", adesea reprezentat ca "[UNK]" sau "<unk>". În general, este un indiciu rău dacă vedeți că tokenizatorul produce o mulțime de astfel de token-uri, deoarece nu a fost capabil să recupereze reprezentarea sensibilă a unui cuvânt și veți pierde informații pe parcurs. Scopul elaborării vocabularului este de a face în așa fel încât tokenizatorul să tokenizeze cât mai puține cuvinte posibil în tokenul necunoscut. + +O modalitate de a reduce numărul de token-uri necunoscute este de a merge un nivel mai adânc, folosind un tokenizer _character-based_. + +## Character-based[[character-based]] + + + + +Tokenizerele character-based împart textul în caractere, și nu în cuvinte. Acest lucru are două beneficii principale: + +- Dimensiunea vocabularului este mult mai mică. +- Există mult mai puține token-uri în afara vocabularului (necunoscute), deoarece fiecare cuvânt poate fi construit din caractere. + +Dar și aici apar unele probleme legate de spații și punctuație: + + +
+ An example of character-based tokenization. + +
+ + +Nici această abordare nu este perfectă. Deoarece reprezentarea se bazează acum pe caractere și nu pe cuvinte, s-ar putea spune că, din punct de vedere intuitiv, este mai puțin relevantă: fiecare caracter nu înseamnă mult în sine, în timp ce în cazul cuvintelor situația este diferită. Totuși, acest lucru variază din nou în funcție de limbă; în chineză, de exemplu, fiecare caracter conține mai multe informații decât un caracter într-o limbă latină. + +Un alt lucru care trebuie luat în considerare este faptul că ne vom trezi cu o cantitate foarte mare de token-uri care vor fi prelucrate de modelul nostru: în timp ce un cuvânt ar fi un singur token cu un tokenizator bazat pe cuvinte, acesta se poate transforma cu ușurință în 10 sau mai multe token-uri atunci când este convertit în caractere. + +Pentru a obține ce este mai bun din ambele lumi, putem utiliza o a treia tehnică care combină cele două abordări: *subword tokenization*. + +## Subword tokenization[[subword-tokenization]] + + + +Algoritmii "Subword Tokenization " se bazează pe principiul conform căruia cuvintele utilizate frecvent nu ar trebui să fie împărțite în cuvinte secundare mai mici, dar cuvintele rare ar trebui să fie descompuse în cuvinte secundare semnificative. + +De exemplu, " annoyingly " ar putea fi considerat un cuvânt rar și ar putea fi descompus în " annoying " și " ly ". Este probabil ca ambele să apară mai frecvent ca subcuvinte de sine stătătoare, în timp ce, în același timp, sensul cuvântului " annoyingly " este păstrat de sensul compus al cuvintelor " annoying " și " ly ". + +Iată un exemplu care arată modul în care un algoritm de subword tokenization ar tokeniza secvența "Let's do tokenization!": + +
+ A subword tokenization algorithm. + +
+ +Aceste părți de cuvinte oferă în cele din urmă o mulțime de semnificații semantice: în exemplul de mai sus, "tokenization" a fost împărțit în "token" și "ization", două cuvinte care au o semnificație semantică, fiind în același timp eficiente din punct de vedere al spațiului (sunt necesare doar două cuvinte pentru a reprezenta un cuvânt lung). Acest lucru ne permite să avem o acoperire relativ bună cu vocabulare de dimensiuni mici și aproape fără token-uri necunoscute. + +Această abordare este utilă în special în limbile aglutinative, cum ar fi turca, în care se pot forma cuvinte complexe (aproape) arbitrar de lungi prin combinarea părților de cuvinte. + +### Și nu numai![[și-nu-numai]] + +Nu este surprinzător faptul că există mult mai multe tehnici. Iată câteva: + +- BPE la nivel de byte, utilizată în GPT-2 +- WordPiece, utilizată în BERT +- SentencePiece sau Unigram, utilizate în mai multe modele multilingve + +Acum ar trebui să cunoașteți destul de bine cum funcționează tokenizerele pentru a începe să utilizați API- + +## Încărcarea și salvarea[[încărcarea-și-salvarea]] + +Încărcarea și salvarea tokenizerelor este la fel de simplă ca în cazul modelelor. De fapt, se bazează pe aceleași două metode: `from_pretrained()` și `save_pretrained()`. Aceste metode vor încărca sau salva algoritmul utilizat de tokenizator (un pic ca *arhitectura* modelului), precum și vocabularul său (un pic ca *weight-urile* modelului). + +Încărcarea tokenizatorului BERT antrenat cu același punct de control ca BERT se face în același mod ca și încărcarea modelului, cu excepția faptului că folosim clasa `BertTokenizer`: + +```py +from transformers import BertTokenizer + +tokenizer = BertTokenizer.from_pretrained("bert-base-cased") +``` + +{#if fw === 'pt'} +Similar cu `AutoModel`, clasa `AutoTokenizer` va prelua clasa tokenizer corespunzătoare din bibliotecă pe baza numelui checkpoint-ului și poate fi utilizată direct cu orice checkpoint: + +{:else} +Similar cu `TFAutoModel`, clasa `AutoTokenizer` va prelua clasa tokenizer corespunzătoare din bibliotecă pe baza numelui checkpoint-ului și poate fi utilizată direct cu orice checkpoint: + +{/if} + +```py +from transformers import AutoTokenizer + +tokenizer = AutoTokenizer.from_pretrained("bert-base-cased") +``` + +Acum putem utiliza tokenizatorul așa cum am arătat în secțiunea anterioară: + +```python +tokenizer("Using a Transformer network is simple") +``` + +```python out +{'input_ids': [101, 7993, 170, 11303, 1200, 2443, 1110, 3014, 102], + 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], + 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]} +``` + +Salvarea unui tokenizer este identică cu salvarea unui model: + +```py +tokenizer.save_pretrained("directory_on_my_computer") +``` + +Vom vorbi mai mult despre `token_type_ids` în [Capitolul 3](/course/chapter3) și vom explica cheia `attention_mask` puțin mai târziu. Mai întâi, să vedem cum sunt generate `input_ids`. Pentru a face acest lucru, va trebui să ne uităm la metodele intermediare ale tokenizatorului. + +## Codificarea[[codificarea]] + + + +Al doilea pas este să convertim aceste token-uri în numere, astfel încât să putem construi un tensor din ele și să le introducem în model. Pentru a face acest lucru, tokenizatorul are un *vocabular*, care este partea pe care o descărcăm atunci când îl instanțiem cu metoda `from_pretrained()`. Din nou, trebuie să folosim același vocabular utilizat atunci când modelul a fost preinstruit. + +Pentru a înțelege mai bine cele două etape, le vom explora separat. Rețineți că vom utiliza unele metode care efectuează părți ale pipeline-ului de tokenizare separat pentru a vă arăta rezultatele intermediare ale acestor etape, dar, în practică, ar trebui să apelați tokenizatorul direct pe intrările dvs. (așa cum se arată în secțiunea 2). + +### Tokenizarea[[tokenizarea]] + +Procesul de tokenizare este realizat prin metoda `tokenize()`: + +```py +from transformers import AutoTokenizer + +tokenizer = AutoTokenizer.from_pretrained("bert-base-cased") + +sequence = "Using a Transformer network is simple" +tokens = tokenizer.tokenize(sequence) + +print(tokens) +``` + +Rezultatul acestei metode este o listă de șiruri de caractere, sau token-uri: + +```python out +['Using', 'a', 'transform', '##er', 'network', 'is', 'simple'] +``` + +Acest tokenizator este un tokenizator de părți de cuvinte: împarte cuvintele până când obține token-uri care pot fi reprezentate de vocabularul său. Acesta este cazul aici cu `transformer`, care este împărțit în două token-uri: `transform` și `##er` + +### De la token-uri la ID-uri de intrare[[de-la-token-uri-la-id-uri-de-intrare]] + +Conversia în ID-uri de intrare este gestionată de metoda de tokenizare `convert_tokens_to_ids()`: + +```py +ids = tokenizer.convert_tokens_to_ids(tokens) + +print(ids) +``` + +```python out +[7993, 170, 11303, 1200, 2443, 1110, 3014] +``` + +Aceste rezultate, odată convertite în tensorul framework-ului corespunzător, pot fi apoi utilizate ca intrări într-un model, așa cum am văzut mai devreme în acest capitol. + + + +✏️ ** Încercați!** Replicați ultimii doi pași (tokenizarea și conversia în ID-uri de intrare) pe propozițiile de intrare pe care le-am folosit în secțiunea 2 ("I've been waiting for a HuggingFace course my whole life." și "I hate this so much!"). Verificați dacă obțineți aceleași ID-uri de intrare pe care le-am obținut mai devreme! + + + +## Decodificare[[decodificare]] + +*Decodificarea* este inversă: din indicii vocabularului, dorim să obținem un șir de caractere. Acest lucru poate fi realizat cu metoda `decode()` după cum urmează: + +```py +decoded_string = tokenizer.decode([7993, 170, 11303, 1200, 2443, 1110, 3014]) +print(decoded_string) +``` + +```python out +'Using a Transformer network is simple' +``` + +Rețineți că metoda `decode` nu numai că convertește indicii înapoi în token-uri, dar și grupează token-urile care fac parte din aceleași cuvinte pentru a produce o propoziție inteligibilă. Acest comportament va fi extrem de util atunci când vom utiliza modele care prezic text nou (fie text generat de un prompt, fie pentru probleme sequence-to-sequence, precum traducerea sau rezumarea). + +Până acum ar trebui să înțelegeți operațiunile atomice pe care le poate gestiona un tokenizator: tokenizarea, conversia în ID-uri și conversia ID-urilor înapoi într-un șir. Cu toate acestea, am atins doar vârful icebergului. În secțiunea următoare, vom aborda limitele metodei noastre și vom vedea cum să le depășim. diff --git a/chapters/rum/chapter2/5.mdx b/chapters/rum/chapter2/5.mdx new file mode 100644 index 000000000..1d71f6188 --- /dev/null +++ b/chapters/rum/chapter2/5.mdx @@ -0,0 +1,338 @@ + + +# Gestionarea secvențelor multiple[[gestionarea-secvențelor-multiple]] + +{#if fw === 'pt'} + + + +{:else} + + + +{/if} + +{#if fw === 'pt'} + +{:else} + +{/if} + +În secțiunea anterioară, am explorat cel mai simplu caz de utilizare: realizarea de inferențe pe o singură secvență de lungime mică. Cu toate acestea, apar deja unele întrebări: + +- Cum gestionăm secvențe multiple? +- Cum gestionăm secvențe multiple *de lungimi diferite*? +- Indicii vocabularului sunt singurele intrări care permit unui model să funcționeze bine? +- Există o secvență prea lungă? + +Să vedem ce tipuri de probleme prezintă aceste întrebări și cum le putem rezolva folosind API-ul 🤗 Transformers. + + +## Modelele așteaptă un lot de intrări[[modelele-așteaptă-un-lot-de-intrări]] + +În exercițiul anterior ați văzut cum secvențele sunt transformate în liste de numere. Să convertim această listă de numere într-un tensor și să o transmitem modelului: + +{#if fw === 'pt'} +```py +import torch +from transformers import AutoTokenizer, AutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) +model = AutoModelForSequenceClassification.from_pretrained(checkpoint) + +sequence = "I've been waiting for a HuggingFace course my whole life." + +tokens = tokenizer.tokenize(sequence) +ids = tokenizer.convert_tokens_to_ids(tokens) +input_ids = torch.tensor(ids) +# Această linie va eșua. +model(input_ids) +``` + +```python out +IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1) +``` +{:else} +```py +import tensorflow as tf +from transformers import AutoTokenizer, TFAutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) +model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint) + +sequence = "I've been waiting for a HuggingFace course my whole life." + +tokens = tokenizer.tokenize(sequence) +ids = tokenizer.convert_tokens_to_ids(tokens) +input_ids = tf.constant(ids) +# This line will fail. +model(input_ids) +``` + +```py out +InvalidArgumentError: Input to reshape is a tensor with 14 values, but the requested shape has 196 [Op:Reshape] +``` +{/if} + +Oh, nu! De ce a eșuat? Am urmat pașii din pipeline-ul din secțiunea 2. + +Problema este că am trimis o singură secvență către model, în timp ce modelele 🤗 Transformers așteaptă în mod implicit mai multe propoziții. Aici am încercat să facem tot ce a făcut tokenizatorul în fundal atunci când l-am aplicat unei `secvențe`. Dar, dacă vă uitați cu atenție, veți vedea că tokenizatorul nu a convertit doar lista de ID-uri de intrare într-un tensor, ci a adăugat și o dimensiune peste aceasta: + +{#if fw === 'pt'} +```py +tokenized_inputs = tokenizer(sequence, return_tensors="pt") +print(tokenized_inputs["input_ids"]) +``` + +```python out +tensor([[ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, + 2607, 2026, 2878, 2166, 1012, 102]]) +``` +{:else} +```py +tokenized_inputs = tokenizer(sequence, return_tensors="tf") +print(tokenized_inputs["input_ids"]) +``` + +```py out + +``` +{/if} + +Să încercăm din nou și să adăugăm o nouă dimensiune: + +{#if fw === 'pt'} +```py +import torch +from transformers import AutoTokenizer, AutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) +model = AutoModelForSequenceClassification.from_pretrained(checkpoint) + +sequence = "I've been waiting for a HuggingFace course my whole life." + +tokens = tokenizer.tokenize(sequence) +ids = tokenizer.convert_tokens_to_ids(tokens) + +input_ids = torch.tensor([ids]) +print("Input IDs:", input_ids) + +output = model(input_ids) +print("Logits:", output.logits) +``` +{:else} +```py +import tensorflow as tf +from transformers import AutoTokenizer, TFAutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) +model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint) + +sequence = "I've been waiting for a HuggingFace course my whole life." + +tokens = tokenizer.tokenize(sequence) +ids = tokenizer.convert_tokens_to_ids(tokens) + +input_ids = tf.constant([ids]) +print("Input IDs:", input_ids) + +output = model(input_ids) +print("Logits:", output.logits) +``` +{/if} + +Imprimăm ID-urile de intrare, precum și logit-urile rezultate - iată rezultatul: + +{#if fw === 'pt'} +```python out +Input IDs: [[ 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012]] +Logits: [[-2.7276, 2.8789]] +``` +{:else} +```py out +Input IDs: tf.Tensor( +[[ 1045 1005 2310 2042 3403 2005 1037 17662 12172 2607 2026 2878 + 2166 1012]], shape=(1, 14), dtype=int32) +Logits: tf.Tensor([[-2.7276208 2.8789377]], shape=(1, 2), dtype=float32) +``` +{/if} + +Gruparea în loturi este acțiunea de a trimite mai multe propoziții prin model, toate odată. Dacă aveți o singură propoziție, puteți crea un lot cu o singură secvență: + +``` +batched_ids = [ids, ids] +``` + +Acesta este un lot de două secvențe identice! + + + +✏️ ** Încercați!** Convertiți această listă `batched_ids` într-un tensor și treceți-o prin modelul dumneavoastră. Verificați dacă obțineți aceleași logits ca înainte (dar de două ori)! + + + +Gruparea în loturi permite modelului să funcționeze atunci când îi furnizați mai multe secvențe. Utilizarea mai multor secvențe este la fel de simplă ca și crearea unui lot cu o singură secvență. Există însă o a doua problemă. Atunci când încercați să combinați două (sau mai multe) propoziții, acestea pot avea lungimi diferite. Dacă ați mai lucrat vreodată cu tensori, știți că aceștia trebuie să aibă o formă dreptunghiulară, deci nu veți putea converti direct lista de ID-uri de intrare într-un tensor. Pentru a rezolva această problemă, de obicei *umplem* datele de intrare. + +## Umplerea datelor de intrare[[umplerea-datelor-de-intrare]] + +Următoarea serie de liste nu poate fi convertită într-un tensor: + +```py no-format +batched_ids = [ + [200, 200, 200], + [200, 200] +] +``` + +Pentru a ocoli acest lucru, vom folosi *padding-ul* pentru ca tensorii noștri să aibă o formă dreptunghiulară. Padding-ul (umplerea datelor) asigură că toate propozițiile noastre au aceeași lungime prin adăugarea unui cuvânt special numit *padding token* la propozițiile cu mai puține valori. De exemplu, dacă aveți 10 propoziții cu 10 cuvinte și 1 propoziție cu 20 de cuvinte, padding-ul va asigura că toate propozițiile au 20 de cuvinte. În exemplul nostru, tensorul rezultat arată astfel: + +```py no-format +padding_id = 100 + +batched_ids = [ + [200, 200, 200], + [200, 200, padding_id], +] +``` + +ID-ul token-ului de umplere poate fi găsit în `tokenizer.pad_token_id`. Să-l folosim și să trimitem cele două propoziții prin model în mod separat și grupate împreună: + +{#if fw === 'pt'} +```py no-format +model = AutoModelForSequenceClassification.from_pretrained(checkpoint) + +sequence1_ids = [[200, 200, 200]] +sequence2_ids = [[200, 200]] +batched_ids = [ + [200, 200, 200], + [200, 200, tokenizer.pad_token_id], +] + +print(model(torch.tensor(sequence1_ids)).logits) +print(model(torch.tensor(sequence2_ids)).logits) +print(model(torch.tensor(batched_ids)).logits) +``` + +```python out +tensor([[ 1.5694, -1.3895]], grad_fn=) +tensor([[ 0.5803, -0.4125]], grad_fn=) +tensor([[ 1.5694, -1.3895], + [ 1.3373, -1.2163]], grad_fn=) +``` +{:else} +```py no-format +model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint) + +sequence1_ids = [[200, 200, 200]] +sequence2_ids = [[200, 200]] +batched_ids = [ + [200, 200, 200], + [200, 200, tokenizer.pad_token_id], +] + +print(model(tf.constant(sequence1_ids)).logits) +print(model(tf.constant(sequence2_ids)).logits) +print(model(tf.constant(batched_ids)).logits) +``` + +```py out +tf.Tensor([[ 1.5693678 -1.3894581]], shape=(1, 2), dtype=float32) +tf.Tensor([[ 0.5803005 -0.41252428]], shape=(1, 2), dtype=float32) +tf.Tensor( +[[ 1.5693681 -1.3894582] + [ 1.3373486 -1.2163193]], shape=(2, 2), dtype=float32) +``` +{/if} + +Este ceva în neregulă cu logit-urile din predicțiile noastre grupate: al doilea rând ar trebui să fie identic cu logit-urile pentru a doua propoziție, dar avem valori complet diferite! + +Acest lucru se datorează faptului că principala caracteristică a modelelor Transformer sunt straturile de atenție care *contextualizează* fiecare token. Acestea vor lua în considerare token-urile de umplutură, deoarece se ocupă de toate token-urile unei secvențe. Pentru a obține același rezultat atunci când trecem propoziții individuale de diferite lungimi prin model sau atunci când trecem un lot cu aceleași propoziții și același umplutură aplicată, trebuie să spunem acelor straturi de atenție să ignore token-urile de umplutură. Acest lucru se realizează prin utilizarea unei măști de atenție (attention mask). + +## Attention masks(măști de atenție)[[attention-masks]] + +*Măștile de atenție* sunt tensori cu exact aceeași formă ca tensorul ID-urilor de intrare, completate cu 0 și 1: valorile 1 indică faptul că ar trebui să se acorde atenție token-urilor corespunzătoare, iar valorile 0 indică faptul că nu ar trebui să se acorde atenție token-urilor corespunzătoare (adică acestea ar trebui ignorate de straturile de atenție ale modelului). + +Să completăm exemplul anterior cu o mască de atenție: + +{#if fw === 'pt'} +```py no-format +batched_ids = [ + [200, 200, 200], + [200, 200, tokenizer.pad_token_id], +] + +attention_mask = [ + [1, 1, 1], + [1, 1, 0], +] + +outputs = model(torch.tensor(batched_ids), attention_mask=torch.tensor(attention_mask)) +print(outputs.logits) +``` + +```python out +tensor([[ 1.5694, -1.3895], + [ 0.5803, -0.4125]], grad_fn=) +``` +{:else} +```py no-format +batched_ids = [ + [200, 200, 200], + [200, 200, tokenizer.pad_token_id], +] + +attention_mask = [ + [1, 1, 1], + [1, 1, 0], +] + +outputs = model(tf.constant(batched_ids), attention_mask=tf.constant(attention_mask)) +print(outputs.logits) +``` + +```py out +tf.Tensor( +[[ 1.5693681 -1.3894582 ] + [ 0.5803021 -0.41252586]], shape=(2, 2), dtype=float32) +``` +{/if} + +Acum obținem aceeași logits pentru a doua propoziție din lot. + +Observăm cum ultima valoare a celei de-a doua secvențe este un ID de umplere, care este o valoare 0 în masca de atenție. + + + +✏️ ** Încercați!** Aplicați manual tokenizarea pe cele două propoziții utilizate în secțiunea 2 ("I've been waiting for a HuggingFace course my whole life." și "I hate this so much!"). Treceți-le prin model și verificați dacă obțineți aceeași logiți ca în secțiunea 2. Acum grupați-le împreună folosind token-ul de umplere, apoi creați masca de atenție corespunzătoare. Verificați dacă obțineți aceleași rezultate atunci când parcurgeți modelul! + + + +## Secvențe mai lungi[[secvențe-mai-lungi]] + +Cu modelele Transformer, există o limită a lungimii secvențelor pe care le putem transmite modelelor. Majoritatea modelelor gestionează secvențe de până la 512 sau 1024 de token-uri și se vor bloca atunci când li se cere să proceseze secvențe mai lungi. Există două soluții la această problemă: + +- Utilizați un model cu o lungime de secvență acceptată mai mare. +- Trunchiați secvențele. + +Modelele au diferite lungimi de secvență acceptate, iar unele sunt specializate în tratarea secvențelor foarte lungi. [Longformer](https://huggingface.co/docs/transformers/model_doc/longformer) este un exemplu, iar altul este [LED](https://huggingface.co/docs/transformers/model_doc/led). Dacă lucrați la o sarcină care necesită secvențe foarte lungi, vă recomandăm să aruncați o privire la aceste modele. + +În caz contrar, vă recomandăm să vă trunchiați secvențele prin specificarea parametrului `max_sequence_length`: +```py +sequence = sequence[:max_sequence_length] +``` diff --git a/chapters/rum/chapter2/6.mdx b/chapters/rum/chapter2/6.mdx new file mode 100644 index 000000000..a95a92d56 --- /dev/null +++ b/chapters/rum/chapter2/6.mdx @@ -0,0 +1,164 @@ + + +# Să punem totul cap la cap[[să-punem-totul-cap-la-cap]] + +{#if fw === 'pt'} + + + +{:else} + + + +{/if} + +În ultimele secțiuni, ne-am străduit să facem cea mai mare parte a muncii manual. Am explorat modul în care funcționează tokenizerele și am analizat tokenizarea, conversia în ID-uri de intrare, padding, trunchiere și măști de atenție. + +Cu toate acestea, după cum am văzut în secțiunea 2, API-ul 🤗 Transformers poate gestiona toate acestea pentru noi cu o funcție de nivel înalt în care ne vom adânci aici. Atunci când apelați `tokenizer` direct pe propoziție, primiți înapoi intrări care sunt gata să treacă prin modelul dvs: + +```py +from transformers import AutoTokenizer + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) + +sequence = "I've been waiting for a HuggingFace course my whole life." + +model_inputs = tokenizer(sequence) +``` + +Aici, variabila `model_inputs` conține tot ceea ce este necesar pentru ca un model să funcționeze bine. Pentru DistilBERT, aceasta include ID-urile de intrare, precum și masca de atenție. Alte modele care acceptă intrări suplimentare le vor avea, de asemenea, la ieșire prin obiectul `tokenizer`. + +După cum vom vedea în câteva exemple de mai jos, această metodă este foarte eficientă. În primul rând, poate tokeniza o singură secvență: + +```py +sequence = "I've been waiting for a HuggingFace course my whole life." + +model_inputs = tokenizer(sequence) +``` + +De asemenea, gestionează mai multe secvențe simultan, fără nicio modificare a API-ului: + +```py +sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] + +model_inputs = tokenizer(sequences) +``` + +Acesta poate umple în funcție de mai multe obiective: + +```py +# Va umple secvențele până la lungimea maximă a secvenței +model_inputs = tokenizer(sequences, padding="longest") + +# Va umple secvențele până la lungimea maximă a modelului +# (512 pentru BERT sau DistilBERT) +model_inputs = tokenizer(sequences, padding="max_length") + +# Va umple secvențele până la lungimea maximă specificată +model_inputs = tokenizer(sequences, padding="max_length", max_length=8) +``` + +De asemenea, poate trunchia secvențele: + +```py +sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] + +# Va trunchia secvențele care sunt mai lungi decât lungimea maximă a modelului +# (512 pentru BERT sau DistilBERT) +model_inputs = tokenizer(sequences, truncation=True) + +# Va trunchia secvențele care sunt mai lungi decât lungimea maximă specificată +model_inputs = tokenizer(sequences, max_length=8, truncation=True) +``` + +Obiectul `tokenizer` poate gestiona conversia în tensori specifici framework-ului, care pot fi apoi trimiși direct la model. De exemplu, în următorul exemplu de cod, solicităm tokenizatorului să returneze tensori din diferite cadre - `„pt”` returnează tensori PyTorch, `„tf”` returnează tensori TensorFlow, iar `„np”` returnează matrici NumPy: + +```py +sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] + +# Returnează tensori PyTorch +model_inputs = tokenizer(sequences, padding=True, return_tensors="pt") + +# Returnează tensori TensorFlow +model_inputs = tokenizer(sequences, padding=True, return_tensors="tf") + +# Returnează array-uri NumPy +model_inputs = tokenizer(sequences, padding=True, return_tensors="np") +``` + +## Token-uri speciale[[token-uri-speciale]] + +Dacă aruncăm o privire la ID-urile de intrare returnate de tokenizer, vom vedea că sunt puțin diferite de cele pe care le-am avut mai devreme: + +```py +sequence = "I've been waiting for a HuggingFace course my whole life." + +model_inputs = tokenizer(sequence) +print(model_inputs["input_ids"]) + +tokens = tokenizer.tokenize(sequence) +ids = tokenizer.convert_tokens_to_ids(tokens) +print(ids) +``` + +```python out +[101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102] +[1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012] +``` + +Un token ID a fost adăugat la început, iar unul la sfârșit. Să decodificăm cele două secvențe de ID-uri de mai sus pentru a vedea despre ce este vorba: + +```py +print(tokenizer.decode(model_inputs["input_ids"])) +print(tokenizer.decode(ids)) +``` + +```python out +"[CLS] i've been waiting for a huggingface course my whole life. [SEP]" +"i've been waiting for a huggingface course my whole life." +``` + +Tokenizatorul a adăugat cuvântul special `[CLS]` la început și cuvântul special `[SEP]` la sfârșit. Acest lucru se datorează faptului că modelul a fost preinstruit cu aceste cuvinte, deci pentru a obține aceleași rezultate pentru inferență trebuie să le adăugăm și pe acestea. Rețineți că unele modele nu adaugă cuvinte speciale sau adaugă cuvinte diferite; de asemenea, modelele pot adăuga aceste cuvinte speciale doar la început sau doar la sfârșit. În orice caz, tokenizatorul știe care sunt cele așteptate și se va ocupa de acest lucru pentru dumneavoastră. + +## Încheiere: De la tokenizer la model[[încheiere-de-la-tokenizator--model]] + +Acum că am văzut toți pașii individuali pe care îi utilizează obiectul `tokenizer` atunci când este aplicat pe texte, să vedem o ultimă dată cum poate gestiona secvențe multiple (padding!), secvențe foarte lungi (trunchiere!) și mai multe tipuri de tensori cu API-ul său principal: + +{#if fw === 'pt'} +```py +import torch +from transformers import AutoTokenizer, AutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) +model = AutoModelForSequenceClassification.from_pretrained(checkpoint) +sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] + +tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="pt") +output = model(**tokens) +``` +{:else} +```py +import tensorflow as tf +from transformers import AutoTokenizer, TFAutoModelForSequenceClassification + +checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" +tokenizer = AutoTokenizer.from_pretrained(checkpoint) +model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint) +sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"] + +tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="tf") +output = model(**tokens) +``` +{/if} diff --git a/chapters/rum/chapter2/7.mdx b/chapters/rum/chapter2/7.mdx new file mode 100644 index 000000000..2e6f1175c --- /dev/null +++ b/chapters/rum/chapter2/7.mdx @@ -0,0 +1,19 @@ +# Utilizarea de bază este completă![[utilizarea-de-bază-este-completă]] + + + + +Ați făcut o treabă excelentă dacă ați urmat cursul până aici! Pentru a sintetiza, în acest capitol ați: + +- Ați învățat elementele de bază ale unui model Transformer. +- Ați învățat ce formează un pipeline de tokenizare. +- Ați văzut cum să utilizați un model Transformer în practică. +- Ați învățat cum să folosiți un tokenizer pentru a converti textul în tensori care sunt inteligibili pentru model. +- Am configurat împreună un tokenizer și un model pentru a ajunge de la text la predicții. +- Am învățat limitările ID-urilor de intrare și am învățat despre attention masks(măști de atenție). +- V-ați antrenat cu ajutorul metodelor versatile și configurabile ale tokenizatorului. + +De acum înainte, ar trebui să puteți naviga liber prin documentele 🤗 Transformers: vocabularul va suna familiar și ați văzut deja metodele pe care le veți utiliza în majoritatea timpului. \ No newline at end of file diff --git a/chapters/rum/chapter2/8.mdx b/chapters/rum/chapter2/8.mdx new file mode 100644 index 000000000..c41f27936 --- /dev/null +++ b/chapters/rum/chapter2/8.mdx @@ -0,0 +1,310 @@ + + + + +# End-of-chapter quiz[[end-of-chapter-quiz]] + + + +### 1. What is the order of the language modeling pipeline? + + + +### 2. How many dimensions does the tensor output by the base Transformer model have, and what are they? + +