Buckets:
టోకనైజర్లు[[tokenizers]]
టోకనైజర్లు NLP పైప్లైన్లోని ముఖ్య భాగాల్లో ఒకటి. వీటి లక్ష్యం ఒక్కటే: టెక్స్ట్ను మోడల్ ప్రాసెస్ చేయగలిగే డేటాగా మార్చడం. మోడళ్లు సంఖ్యలతోనే పని చేయగలవు, కాబట్టి టోకనైజర్లు మన టెక్స్ట్ ఇన్పుట్లను సంఖ్యాత్మక డేటాగా మారుస్తాయి.
ఈ విభాగంలో, టోకనైజేషన్ పైప్లైన్లో నిజానికి ఏమి జరుగుతుందో పరిశీలిద్దాం.
NLP పనుల్లో సాధారణంగా ప్రాసెస్ చేయబడే డేటా raw text. ఉదాహరణకు:
Jim Henson was a puppeteer
అయితే, మోడళ్లు సంఖ్యలను మాత్రమే ప్రాసెస్ చేయగలవు కాబట్టి, raw textను సంఖ్యలుగా మార్చే మార్గాన్ని కనుగొనాలి. అదే టోకనైజర్ చేసే పని, మరియు దీన్ని చేయడానికి అనేక పద్ధతులు ఉన్నాయి. లక్ష్యం ఏమిటంటే, మోడల్కి ఎక్కువ అర్థమయ్యే — సాధ్యమైతే, అత్యంత చిన్న — ప్రతినిధిని (representation) కనుగొనడం.
ఇప్పుడు కొన్ని టోకనైజేషన్ అల్గోరిథమ్ల ఉదాహరణలను చూసి, టోకనైజేషన్ గురించి మీకు ఉండొచ్చిన కొన్ని ప్రశ్నలకు సమాధానాలు కనుగొనడానికి ప్రయత్నిద్దాం.
పదాల ఆధారంగా[[word-based]]
మెదట గుర్తొచ్చే టోకనైజర్ రకం word-based టోకనైజర్. కొద్దిపాటి నియమాలతో సులభంగా సెటప్ చేయవచ్చు, ఉపయోగించడం కూడా తేలిక, మరియు చాలా సందర్భాల్లో బాగానే ఫలితాలు ఇస్తుంది.
ఉదాహరణకు, క్రింది బొమ్మలో లక్ష్యం ఏమిటంటే, raw text ను పదాలుగా విభజించి, ప్రతి పదానికి సంఖ్యాత్మక ప్రతినిధిని కనుగొనడం:
టెక్స్ట్ను విభజించడానికి విభిన్న పద్ధతులు ఉన్నాయి. ఉదాహరణకు, Python లో split() ఫంక్షన్ను ఉపయోగించి, whitespace ఆధారంగా పదాలుగా విభజించవచ్చు:
tokenized_text = "Jim Henson was a puppeteer".split()
print(tokenized_text)
['Jim', 'Henson', 'was', 'a', 'puppeteer']
కొన్ని word tokenizers పంక్చుయేషన్ కోసం అదనపు నియమాలను కూడా కలిగి ఉంటాయి. ఇటువంటి టోకనైజర్తో మనకు చాలా పెద్ద "vocabulary" రావచ్చు — ఇక్కడ vocabulary అంటే మన corpus లో ఉన్న అన్ని స్వతంత్ర tokens సంఖ్య.
ప్రతీ పదానికి ఒక ID కేటాయిస్తారు; అది 0 నుండి vocabulary పరిమాణం వరకు ఉంటుంది. మోడల్ ప్రతి పదాన్ని గుర్తించడానికి ఈ IDs ను ఉపయోగిస్తుంది.
ఒక భాషలోని అన్ని పదాలను word-based టోకనైజర్ ద్వారా కవర్ చేయాలంటే, ప్రతి పదానికి ఒక్కో identifier ఉండాలి; ఇది చాలా పెద్ద సంఖ్యలో tokensను ఉత్పత్తి చేస్తుంది. ఉదాహరణకు, ఆంగ్లంలో 500,000 కంటే ఎక్కువ పదాలు ఉన్నాయి, కాబట్టి ప్రతి పదాన్ని ఒక input ID కి మ్యాప్ చేయడానికి అంతటి IDs ను నిర్వహించాలి.
ఇదంతా కాకుండా, "dog" మరియు "dogs" లాంటి పదాలను మోడల్ మొదట్లో పూర్తిగా వేర్వేరుగా చూస్తుంది — "dog" మరియు "dogs" పరస్పర సంబంధం లేకుండా కనిపిస్తాయి. ఇదే విషయం "run" మరియు "running" వంటి ఇతర పదాలకు కూడా వర్తిస్తుంది.
చివరగా, vocabulary లో లేని పదాలను సూచించడానికి ఒక ప్రత్యేక token అవసరం. దీన్ని సాధారణంగా "unknown" token అంటారు, " [UNK] " లేదా "<unk>" వంటివి. టోకనైజర్ చాలా ఎక్కువ unknown tokens ఉత్పత్తి చేస్తూ ఉంటే, అది మంచిది కాదు — ఎందుకంటే అది ఆ పదానికి సరైన ప్రతినిధిని కనుగొనలేకపోయింది, మధ్యలో సమాచారం కోల్పోతున్నామన్నమాట. కాబట్టి vocabulary రూపొందించేప్పుడు లక్ష్యం ఏమిటంటే, tokenizer వీలైనంత తక్కువ పదాలను unknown token గా మార్చేలా ఉండాలి.
ఇలాంటి unknown tokens సంఖ్యను తగ్గించడానికి, మనం ఒక స్థాయి లోతుగా వెళ్లి character-based టోకనైజర్ను ఉపయోగించవచ్చు.
అక్షరాల ఆధారంగా[[character-based]]
Character-based టోకనైజర్లు టెక్స్ట్ను పదాల కంటే, అక్షరాలుగా విభజిస్తాయి. దీనికి రెండు ప్రధాన ప్రయోజనాలు ఉన్నాయి:
- vocabulary చాలా చిన్నదిగా ఉంటుంది.
- out-of-vocabulary (unknown) tokens చాలా తక్కువగా ఉంటాయి, ఎందుకంటే ప్రతి పదాన్ని అక్షరాల నుంచి నిర్మించవచ్చు.
కానీ ఇక్కడ కూడా spaces మరియు పంక్చుయేషన్ గురించి కొన్ని ప్రశ్నలు వస్తాయి:
ఈ విధానం కూడా పరిపూర్ణం కాదు. ప్రతినిధి ఇప్పుడు పదాల ఆధారంగా కాకుండా అక్షరాల ఆధారంగా ఉందని గమనించండి; సహజంగానే చూసుకుంటే, ఒక్కో అక్షరం అంత అర్థవంతం కాకపోవచ్చు, కానీ ఒక్కో పదం మాత్రం సాధారణంగా అర్థవంతంగానే ఉంటుంది.
అయితే ఇది కూడా భాషపై ఆధారపడి ఉంటుంది — ఉదాహరణకు, చైనీస్లో ఒక్కో అక్షరమే చాలా సమాచారం కలిగిఉంటుంది, కానీ లాటిన్ లిపి భాషల్లో అది తక్కువ.
మరికొక విషయం ఏమిటంటే, ఈ విధానంతో మన మోడల్ ప్రాసెస్ చేయాల్సిన tokens సంఖ్య చాలా పెరుగుతుంది: word-based టోకనైజర్లో ఒక పదానికి ఒకే token ఉంటే, character-based టోకనైజర్లో అదే పదం సులభంగా 10 లేదా అంతకంటే ఎక్కువ tokens గా మారిపోతుంది.
ఇద్దరిలోనూ ఉన్న మంచితనాన్ని పొందడానికి, మూడో పద్ధతిని ఉపయోగించవచ్చు: subword tokenization.
సబ్వర్డ్ టోకనైజేషన్[[subword-tokenization]]
Subword టోకనైజేషన్ అల్గోరిథమ్ల ప్రాథమిక సూత్రం ఏమిటంటే:
తరచుగా వాడే పదాలను చిన్న subwords గా విభజించకూడదు, కానీ అరుదుగా వచ్చే పదాలను అర్థవంతమైన subwords గా విభజించాలి.
ఉదాహరణకు, "annoyingly" అనే పదం అరుదుగా వస్తుంది, కాబట్టి దాన్ని "annoying" మరియు "ly" గా విభజించవచ్చు. ఇవి రెండూ సొంతంగా subwords గా ఎక్కువగా కనిపించే అవకాశం ఉంది, అలాగే "annoying" + "ly" కలయిక "annoyingly" అనే భావాన్ని కూడా నిలుపుతుంది.
"Let's do tokenization!" అనే వాక్యానికి ఒక subword టోకనైజేషన్ అల్గోరిథమ్ ఈ విధంగా టోకనైజ్ చేస్తుందనుకోండి:
ఇలాంటి subwords మంచి semantic అర్థాన్ని ఇస్తాయి. ఉదాహరణలో "tokenization" ను "token" మరియు "ization" గా విభజించారు — ఇవి రెండూ semantic meaning కలిగిన tokens, అలాగే space-efficient కూడా (పొడవైన పదాన్ని సూచించడానికి కేవలం రెండు tokens సరిపోతాయి).
దీంతో చిన్న vocabularies తోనే మంచి coverage పొందగలం, unknown tokens కూడా దాదాపు ఉండవు.
ఈ విధానం Turkish లాంటి agglutinative భాషల్లో మరింత ఉపయోగకరంగా ఉంటుంది, ఎందుకంటే అక్కడ subwords ను కలిపి చాలా పొడవైన సమిష్టి పదాలు సులభంగా తయారు చేయవచ్చు.
ఇంకా చాలా![[and-more]]
అందుబాటులో ఇంకా చాలా tokenization పద్ధతులు ఉండటం ఆశ్చర్యకరం కాదు. కొన్ని ముఖ్యమైనవి:
- Byte-level BPE — GPT-2 లో ఉపయోగించిన పద్ధతి
- WordPiece — BERT లో ఉపయోగించబడింది
- SentencePiece లేదా Unigram — కొన్ని multilingual మోడళ్లలో ఉపయోగిస్తారు
ఇప్పటికి, టోకనైజర్లు ఎలా పనిచేస్తాయో అర్థం చేసుకుని, API తో పని చేయడానికి మీ వద్ద సరిపడిన పునాదులు ఉన్నాయి.
లోడ్ చేయడం మరియు సేవ్ చేయడం[[loading-and-saving]]
టోకనైజర్లను లోడ్ చేయడం, సేవ్ చేయడం కూడా మోడళ్ల మాదిరిగానే సులభం. నిజానికి, ఇవి కూడా అదే రెండు పద్ధతులపై ఆధారపడి ఉంటాయి: from_pretrained() మరియు save_pretrained().
ఈ పద్ధతులు టోకనైజర్ ఉపయోగించే అల్గోరిథమ్ (మోడల్ యొక్క architecture లాంటిది) తో పాటు దాని vocabulary (మోడల్ weights లాంటిది) ను కూడా లోడ్ చేయడం లేదా సేవ్ చేయడం చేస్తాయి.
BERT తో ప్రీట్రైన్ చేయబడిన అదే checkpoint కు సంబంధించిన BERT tokenizer ను లోడ్ చేయడం, మోడల్ లోడ్ చేయడంలా ఉంటుంది, కానీ ఇక్కడ మనం BertTokenizer క్లాస్ను ఉపయోగిస్తాము:
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
AutoModel మాదిరిగానే, AutoTokenizer క్లాస్ కూడా checkpoint పేరును ఆధారంగా తీసుకుని, లైబ్రరీలోని సరైన tokenizer క్లాస్ను ఎంచుకుంటుంది, మరియు ఏ checkpoint తోనైనా నేరుగా ఉపయోగించవచ్చు:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
ఇప్పుడు గత విభాగంలో చూసినట్లే tokenizer ను ఉపయోగించవచ్చు:
tokenizer("Using a Transformer network is simple")
{'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]}
టోకనైజర్ను సేవ్ చేయడం కూడా మోడల్ సేవ్ చేసినట్లే ఉంటుంది:
tokenizer.save_pretrained("directory_on_my_computer")
token_type_ids గురించి Chapter 3 లో మరింతగా మాట్లాడతాం, అలాగే attention_mask కీ గురించి కాస్త తర్వాత వివరిస్తాము.
ముందుగా, input_ids ఎలా రూపొందించబడతాయో చూద్దాం. అందుకు tokenizer లోని intermediate methods ను పరిశీలించాలి.
Encoding[[encoding]]
టెక్స్ట్ను సంఖ్యలుగా మార్చే ప్రక్రియను encoding అంటారు. ఇది రెండు దశల్లో జరుగుతుంది: ముందుగా tokenization, తరువాత వాటిని input IDs గా మార్చడం.
ముందు చూశినట్లుగా, మొదటి దశలో టెక్స్ట్ను పదాలుగా (లేదా పద భాగాలుగా, punctuation చిహ్నాలుగా మొదలైనవి) విభజిస్తారు; వీటినే సాధారణంగా tokens అంటారు. ఈ ప్రక్రియ ఎలా జరగాలి అన్నదానికి అనేక నియమాలు ఉండవచ్చు, అందుకే మనం tokenizer ను instantiate చేయేటప్పుడు మోడల్ పేరును ఇస్తాం — మోడల్ ప్రీట్రైనింగ్ సమయంలో ఉపయోగించిన అదే నియమాలను ఇక్కడ కూడా ఉపయోగించడానికి.
రెండవ దశలో, ఆ tokens ను సంఖ్యలుగా మార్చుతాం, తద్వారా వాటితో టెన్సర్ను నిర్మించి మోడల్కు పంపగలం. దీని కోసం tokenizer వద్ద ఒక vocabulary ఉంటుంది — from_pretrained() పద్ధతితో instantiate చేసినప్పుడు డౌన్లోడ్ అయ్యే భాగం ఇదే.
ఇక్కడ కూడా, మోడల్ ప్రీట్రైనింగ్ సమయంలో ఉపయోగించిన అదే vocabulary ను ఉపయోగించాలి.
ఈ రెండు దశలను మెరుగ్గా అర్థం చేసుకోవడానికి, వాటిని వేర్వేరుగా పరిశీలిద్దాం. గమనించాల్సిన విషయం ఏమిటంటే, ఇక్కడ మనం tokenization పైప్లైన్లోని భాగాలను విడివిడిగా చూపే కొన్ని methods ను ఉపయోగిస్తాము, intermediate ఫలితాలను చూడటానికి. కానీ ఆచరణలో, మీరు ముందున్న సెక్షన్ 2 లో చూపినట్లుగా, మీ ఇన్పుట్లపై tokenizer ను నేరుగా కాల్ చేయాల్సిందే.
Tokenization[[tokenization]]
టోకనైజేషన్ ప్రక్రియ tokenizer యొక్క tokenize() పద్ధతి ద్వారా జరుగుతుంది:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
sequence = "Using a Transformer network is simple"
tokens = tokenizer.tokenize(sequence)
print(tokens)
ఈ పద్ధతి ఫలితంగా stringల జాబితా వస్తుంది — ఇవే tokens:
['Using', 'a', 'transform', '##er', 'network', 'is', 'simple']
ఈ tokenizer ఒక subword tokenizer: ఇది తన vocabularyలో ఉన్న subwords వచ్చే వరకు పదాలను చిన్న భాగాలుగా విభజిస్తుంది. ఇక్కడ transformer అనే పదం transform మరియు ##er అనే రెండు tokens గా విభజించబడింది.
Tokens నుండి input IDs వరకు[[from-tokens-to-input-ids]]
Tokens ను input IDs గా మార్చడం tokenizer లోని convert_tokens_to_ids() పద్ధతి ద్వారా జరుగుతుంది:
ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids)
[7993, 170, 11303, 1200, 2443, 1110, 3014]
ఈ outputs ను సరైన framework tensor గా మార్చిన తర్వాత, ఇవి ఈ అధ్యాయంలో ముందుగా చూసినట్లుగానే మోడల్కు ఇన్పుట్లుగా ఉపయోగించవచ్చు.
✏️ ప్రయత్నించండి! సెక్షన్ 2 లో ఉపయోగించిన రెండు వాక్యాలపై ("I've been waiting for a HuggingFace course my whole life." మరియు "I hate this so much!") ఈ చివరి రెండు దశలను (tokenization మరియు input IDs గా మార్పు) మళ్లీ చేయండి. మీరు ముందుగా చూసినట్లే అదే input IDs వస్తున్నాయో లేదో తనిఖీ చేయండి!
Decoding[[decoding]]
Decoding అంటే పక్కదారి — vocabulary indices నుంచి మళ్లీ string కు రావడం. ఇది decode() పద్ధతి ద్వారా చేయవచ్చు:
decoded_string = tokenizer.decode([7993, 170, 11303, 1200, 2443, 1110, 3014])
print(decoded_string)
'Using a Transformer network is simple'
decode పద్ధతి indices ను tokens గా మాత్రమే మార్చదు;
ముందు ఒకే పదానికి చెందిన subword tokens ను మళ్లీ కలిపి, చదవగలిగే వాక్యంగా మార్చుతుంది.
ఈ ప్రవర్తన, text జనరేషన్ చేసే మోడళ్లతో పని చేస్తున్నప్పుడు (prompt నుంచి text ఉత్పత్తి చేయడం, లేదా translation, summarization వంటి sequence-to-sequence సమస్యల్లో) చాలా ఉపయోగకరంగా ఉంటుంది.
ఇప్పటికే టోకనైజర్ చేయగలిగే atomic operations — tokenization, IDs కు మార్పు, మరియు IDs ను తిరిగి string గా మార్చడం — మీకు అర్థమై ఉండాలి.
అయితే ఇది ఐస్బర్గ్ పైభాగం మాత్రమే. తదుపరి విభాగంలో, ఈ విధానాన్ని గరిష్ట స్థాయికి తీసుకెళ్లి, దానివల్ల వచ్చే పరిమితులను ఎలా అధిగమించాలో చూస్తాం.
Xet Storage Details
- Size:
- 22.3 kB
- Xet hash:
- 8705ea54331b693a0d5c9c6673ac5805e54958341fcefb73f0b08b7c8a5701b4
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.