Buckets:

rtrm's picture
|
download
raw
20.8 kB

పైప్‌లైన్ వెనుక

ఇప్పుడు ఒక పూర్తి ఉదాహరణతో ప్రారంభిద్దాం. అధ్యాయం 1లో మనం క్రింది కోడ్‌ను నడిపినప్పుడు వెనుకపట్లో ఏమి జరిగిందో చూద్దాం:

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!",
    ]
)

మరియు మనకు వచ్చిన ఫలితాలు:

[{'label': 'POSITIVE', 'score': 0.9598047137260437},
 {'label': 'NEGATIVE', 'score': 0.9994558095932007}]

అధ్యాయం 1లో చూశినట్లుగా, ఈ పైప్‌లైన్ మూడు దశలను కలిపి అమలు చేస్తుంది: ప్రీప్రాసెసింగ్, ఇన్‌పుట్‌లను మోడల్ ద్వారా పంపించడం, మరియు పోస్ట్‌ప్రాసెసింగ్:

ఇప్పుడు ఈ దశలన్నింటినీ త్వరగా పరిశీలిద్దాం.

టోకనైజర్‌తో ప్రీప్రాసెసింగ్[[preprocessing-with-a-tokenizer]]

ఇతర న్యూరల్ నెట్‌వర్క్‌ల మాదిరిగానే, Transformer మోడళ్లు రా టెక్స్ట్‌ను నేరుగా ప్రాసెస్ చేయలేవు. కాబట్టి పైప్‌లైన్‌లో మొదటి దశ పాఠ్యాన్ని మోడల్ అర్థం చేసుకునే సంఖ్యల్లోకి మార్చడం. దీని కోసం మనం టోకనైజర్ ఉపయోగిస్తాము. ఇది కింది పనులకు బాధ్యత వహిస్తుంది:

  • ఇన్‌పుట్‌ను పదాలు, ఉపపదాలు లేదా చిహ్నాలు (ఉదాహరణకు, punctuation)గా విభజించడం — వీటిని tokens అని పిలుస్తారు
  • ప్రతి టోకెన్‌ను ఒక integer కి మ్యాప్ చేయడం
  • మోడల్‌కు ఉపయోగపడే అదనపు ఇన్‌పుట్‌లను జోడించడం

ఈ ప్రీప్రాసెసింగ్ మొత్తం మోడల్‌ను ప్రీట్రెయిన్ చేసినప్పుడు ఎలా జరిగిందో అచ్చుగుద్దినట్లుగా జరగాలి. అందుకే ముందుగా ఆ సమాచారాన్ని Model Hub నుండి డౌన్‌లోడ్ చేసుకోవాలి. దీని కోసం మనం AutoTokenizer క్లాస్ మరియు దాని from_pretrained() పద్ధతిని ఉపయోగిస్తాము. మన మోడల్ యొక్క checkpoint పేరును ఉపయోగించి, ఇది మోడల్ tokenizer కు సంబంధించిన డేటాను ఆటోమేటిక్‌గా తెచ్చి cache లో భద్రపరుస్తుంది (దాంతో మీరు క్రింది కోడ్‌ను మొదటిసారి నడిపినప్పుడు మాత్రమే అది డౌన్‌లోడ్ అవుతుంది).

sentiment-analysis పైప్‌లైన్ యొక్క డిఫాల్ట్ checkpoint distilbert-base-uncased-finetuned-sst-2-english (దాని మోడల్ కార్డ్‌ను ఇక్కడ చూడవచ్చు). కాబట్టి మనం ఈ క్రింది కోడ్‌ను నడుపుతాము:

from transformers import AutoTokenizer

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

టోకనైజర్ మనకు లభించిన తర్వాత, మనం వాక్యాలను నేరుగా దానిలోకి పంపవచ్చు, మరియు అది మోడల్‌కు ఇవ్వడానికి సిద్ధమైన dictionary ని తిరిగి ఇస్తుంది! ఇప్పుడు చేయవలసింది ఒక్కటే ఉంది: input IDs లిస్ట్‌ను tensors గా మార్చడం.

🤗 Transformers ను ఉపయోగించినప్పుడు ఏ ML framework backend గా వాడబడుతుందో గురించి ఆందోళన చెందాల్సిన అవసరం లేదు; కొన్ని మోడళ్లకు అది PyTorch కావచ్చు లేదా Flax కావచ్చు. అయితే Transformer మోడళ్లు కేవలం tensors నే ఇన్‌పుట్‌గా స్వీకరిస్తాయి. మీరు tensors గురించి తొలిసారి వింటుంటే, వాటిని NumPy arrays మాదిరిగా ఊహించవచ్చు. NumPy array ఒక scalar (0D), ఒక vector (1D), ఒక matrix (2D), లేదా మరింత dimensions కలిగి ఉండవచ్చు. ఇవన్నీ tensors లాగానే పనిచేస్తాయి; ఇతర ML frameworks లోని tensors కూడా ఇలాగే ప్రవర్తిస్తాయి, మరియు సాధారణంగా NumPy arrays ను తయారు చేసినంత సులభంగానే వాటిని సృష్టించవచ్చు.

మనకు తిరిగి రావలసిన tensor రకాన్ని (PyTorch లేదా సాధారణ NumPy) నిర్ణయించడానికి return_tensors argument ను ఉపయోగిస్తాము:

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)

padding మరియు truncation గురించి ఇప్పుడే ఆందోళన చెందాల్సిన అవసరం లేదు; వాటిని తరువాత వివరిస్తాము. ఇక్కడ గుర్తుపెట్టుకోవలసిన ముఖ్యమైన విషయమేమిటంటే: మీరు ఒక వాక్యం లేదా వాక్యాల జాబితాను పంపవచ్చు, అలాగే మీరు కావలసిన tensor రకాన్ని సూచించవచ్చు (ఏ రకం సూచించకపోతే, ఫలితంగా lists of lists వస్తాయి).

ఇక్కడ PyTorch tensors రూపంలో ఫలితాలు ఎలా ఉంటాయో చూడండి:

{
    '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]
    ])
}

ఆ అవుట్‌పుట్ dictionary లో రెండు keys ఉంటాయి: input_ids మరియు attention_mask. input_idsలో రెండు పంక్తుల integers ఉంటాయి (ప్రతి వాక్యానికి ఒక్కటి), ఇవి ప్రతి వాక్యంలో ఉన్న tokens కు ప్రత్యేకమైన గుర్తింపులు. attention_mask ఏమిటో ఈ అధ్యాయంలో తరువాత వివరిస్తాము.

మోడల్ ద్వారా పంపడం[[going-through-the-model]]

ప్రీట్రెయిన్ చేసిన మోడల్‌ను కూడా మనం టోకనైజర్ మాదిరిగానే డౌన్‌లోడ్ చేసుకోవచ్చు. 🤗 Transformers లో AutoModel క్లాస్ ఉంది, దీనికి కూడా from_pretrained() పద్ధతి ఉంది:

from transformers import AutoModel

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
model = AutoModel.from_pretrained(checkpoint)

ఈ కోడ్ స్నిపెట్‌లో, మనం పైప్‌లైన్‌లో ముందే ఉపయోగించిన అదే checkpoint ను డౌన్‌లోడ్ చేసుకున్నాము (అది ఇప్పటికే cache లో ఉండాలి) మరియు దానితో ఒక model ను సృష్టించుకున్నాము.

ఈ architecture కేవలం base Transformer మాడ్యూల్‌ను మాత్రమే కలిగి ఉంటుంది: కొన్ని ఇన్‌పుట్‌లు ఇచ్చినప్పుడు, ఇది hidden states (లేదా features) అని పిలిచే అవుట్‌పుట్‌లను ఇస్తుంది. ప్రతి మోడల్ ఇన్‌పుట్‌కు, Transformer మోడల్ దాని పై ఉన్న contextual understanding ను ప్రతిబింబించే ఒక high-dimensional వెక్టర్ లభిస్తుంది.

ఇది ఇప్పుడే పూర్తిగా అర్థం కాకపోతే ఆందోళన చెందకండి. దీన్ని తరువాత విపులంగా వివరిస్తాము.

ఈ hidden states కొన్ని సందర్భాల్లో ఉపయోగకరంగా ఉండవచ్చు, కానీ అవి సాధారణంగా మోడల్‌లోని మరో భాగానికి — head — కు ఇన్‌పుట్ అవుతాయి. అధ్యాయం 1లో చూశినట్లుగా, వేర్వేరు పనులు ఒకే architecture తో చేయవచ్చు, కానీ ప్రతి task కు వేర్వేరు head ఉంటుంది.

హై-డైమెన్షనల్ వెక్టర్?[[a-high-dimensional-vector]]

Transformer module నుంచి వచ్చే వెక్టర్ సాధారణంగా పెద్దదే. దీనికి మూడు పరిమాణాలు ఉంటాయి:

  • Batch size (బ్యాచ్ పరిమాణం): ఒకేసారి ప్రాసెస్ చేసే సీక్వెన్స్‌ల సంఖ్య (మన ఉదాహరణలో 2).
  • Sequence length (సీక్వెన్స్ పొడవు): ప్రతి సీక్వెన్స్‌కు సంబంధించిన సంఖ్యాత్మక ప్రతినిధి యొక్క పొడవు (మన ఉదాహరణలో 16).
  • Hidden size (హిడెన్ పరిమాణం): ప్రతి ఇన్‌పుట్ టోకెన్‌కి మోడల్ ఉత్పత్తి చేసే వెక్టర్ యొక్క డైమెన్షన్.

ఈ చివరి విలువ కారణంగా దీనిని "high dimensional" అంటారు. చిన్న మోడళ్లలో hidden size 768గా ఉంటుంది; పెద్ద మోడళ్లలో ఇది 3072 లేదా అంతకంటే ఎక్కువ కావచ్చు.

మనము ప్రీప్రాసెస్ చేసిన ఇన్‌పుట్‌లను మోడల్‌లోకి పంపితే ఇది స్పష్టంగా కనిపిస్తుంది:

outputs = model(**inputs)
print(outputs.last_hidden_state.shape)
torch.Size([2, 16, 768])

🤗 Transformers మోడళ్ల అవుట్‌పుట్‌లు namedtuples లేదా dictionaries లాగా ప్రవర్తిస్తాయి. మీరు వాటిని attributes ద్వారా (మనము చేసినట్లుగా), లేదా key (outputs["last_hidden_state"]), లేదా index ద్వారా (outputs[0]) కూడా యాక్సెస్ చేయవచ్చు.

మోడల్ హెడ్‌లు: సంఖ్యలకు అర్థం చెప్పడం[[model-heads-making-sense-out-of-numbers]]

మోడల్ హెడ్‌లు hidden states అనే హై-డైమెన్షనల్ వెక్టర్లను తీసుకుని వాటిని వేరే డైమెన్షన్‌కి ప్రాజెక్ట్ చేస్తాయి. ఇవి సాధారణంగా ఒకటి లేదా కొన్ని లీనియర్ లేయర్‌లతో రూపొందుతాయి:

Transformer మోడల్ యొక్క అవుట్‌పుట్ నేరుగా మోడల్ హెడ్‌కు పంపబడుతుంది, అక్కడ అది ప్రాసెస్ చేయబడుతుంది.

ఈ చిత్రంలో, మోడల్ తన embeddings layer మరియు దాని తర్వాతి లేయర్‌లతో చూపబడింది. Embeddings layer టోకనైజ్ చేసిన ఇన్‌పుట్‌లోని ప్రతి input ID ను, దానికి సరిపడే token ను ప్రతినిధ్యం చేసే ఒక వెక్టర్‌గా మారుస్తుంది. ఆ తర్వాతి లేయర్‌లు attention mechanism ను ఉపయోగించి ఆ వెక్టర్‌లను మార్చి, వాక్యాల యొక్క తుది ప్రతినిధిని తయారు చేస్తాయి.

🤗 Transformers లో అనేక విభిన్న architectures ఉన్నాయి, ప్రతి ఒక్కటి ఒక నిర్దిష్ట పనిని పరిష్కరించడానికి రూపొంది ఉంటుంది. ఇవి కొన్ని ఉదాహరణలు:

  • *Model (hidden states ను పొందడానికి)
  • *ForCausalLM
  • *ForMaskedLM
  • *ForMultipleChoice
  • *ForQuestionAnswering
  • *ForSequenceClassification
  • *ForTokenClassification
  • ఇంకా మరెన్నో 🤗

మన ఉదాహరణలో, వాక్యాలు positive లేదా negative అని వర్గీకరించడానికి sequence classification head కలిగిన మోడల్ అవసరం. అందువల్ల మనం AutoModel ను కాకుండా AutoModelForSequenceClassification ను ఉపయోగిస్తాము:

from transformers import AutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
outputs = model(**inputs)

ఇప్పుడు మనం అవుట్‌పుట్ యొక్క shape ను చూడగా, dimensionality చాలా తక్కువగా ఉంటుంది: మోడల్ హెడ్, ముందుగా చూసిన హై-డైమెన్షనల్ వెక్టర్లను తీసుకుని, ప్రతి లేబుల్‌కి ఒకటి చొప్పున రెండు విలువలను కలిగిన వెక్టర్లను ఉత్పత్తి చేస్తుంది:

print(outputs.logits.shape)
torch.Size([2, 2])

మనకు రెండు వాక్యాలు మరియు రెండు లేబుల్స్ ఉన్నందున, మోడల్ ఇవ్వబడే ఫలితం 2 x 2 ఆకారంలో ఉంటుంది.

అవుట్‌పుట్‌ను పోస్ట్‌ప్రాసెసింగ్ చేయడం[[postprocessing-the-output]]

మోడల్ నుండి వచ్చే అవుట్‌పుట్ విలువలు స్వతహాగా అర్థమయ్యే విధంగా ఉండకపోవచ్చు. ఒకసారి చూద్దాం:

print(outputs.logits)
tensor([[-1.5607,  1.6123],
        [ 4.1692, -3.3464]], grad_fn=)

మన మోడల్ మొదటి వాక్యానికి [-1.5607, 1.6123] ను, రెండవ వాక్యానికి [ 4.1692, -3.3464] ను అంచనా వేసింది. ఇవి probabilities కావు — ఇవి logits, అంటే మోడల్ చివరి లేయర్ ఉత్పత్తి చేసే raw, unnormalized స్కోర్లు. ఇవి probabilities‌ గా మారాలంటే SoftMax లేయర్ ద్వారా పంపాలి.
(అన్ని 🤗 Transformers మోడళ్లు logits ను 출력 చేస్తాయి, ఎందుకంటే ట్రైనింగ్‌లో loss function సాధారణంగా SoftMax వంటి చివరి activation ను cross-entropy వంటి loss తో కలిపి ఉపయోగిస్తుంది.)

import torch

predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
print(predictions)
tensor([[4.0195e-02, 9.5980e-01],
        [9.9946e-01, 5.4418e-04]], grad_fn=)

ఇప్పుడు మనకు స్పష్టంగా కనిపిస్తోంది: మొదటి వాక్యానికి మోడల్ [0.0402, 0.9598], రెండవ వాక్యానికి [0.9995, 0.0005] probabilities ను ఇచ్చింది. ఇవి అర్థమయ్యే probability స్కోర్లు.

ప్రతి స్థానానికి సంబంధించిన లేబుళ్లను తెలుసుకోవడానికి, మోడల్ యొక్క config లోని id2label లక్షణాన్ని చూడవచ్చు (దీని గురించి తరువాతి విభాగంలో మరింత తెలుసుకుంటాము):

model.config.id2label
{0: 'NEGATIVE', 1: 'POSITIVE'}

ఇప్పుడు మనం ఈ విధంగా నిర్ణయించవచ్చు:

  • మొదటి వాక్యం: NEGATIVE: 0.0402, POSITIVE: 0.9598
  • రెండవ వాక్యం: NEGATIVE: 0.9995, POSITIVE: 0.0005

ఇలా మనం పైప్‌లైన్‌లోని మూడు దశలను విజయవంతంగా పునరుద్ధరించాము: టోకనైజర్‌తో ప్రీప్రాసెసింగ్, మోడల్ ద్వారా పంపించడం, మరియు పోస్ట్‌ప్రాసెసింగ్!
ఇప్పుడు ఈ ప్రతి దశను మరింత లోతుగా పరిశీలిద్దాం.

✏️ ప్రయత్నించండి! మీ స్వంత రెండు (లేదా మరిన్ని) వాక్యాలను ఎంచుకుని వాటిని sentiment-analysis పైప్‌లైన్‌లో నడపండి. తరువాత ఇక్కడ చూపిన దశలను ఒక్కొక్కటిగా పునరావృతం చేసి, అదే ఫలితాలు వస్తున్నాయా చూడండి!

Xet Storage Details

Size:
20.8 kB
·
Xet hash:
357a27980627589bb249744ed7c5ed389df8845e518f230a7a4c275dfbd9582b

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.