Using a Customized Mannequin
Whereas the method of constructing and fine-tuning a mannequin is just not the intent of this venture, it is very important perceive how a mannequin could be added to this course of.
# Filename: prepare.pyimport torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from datasets import load_dataset
from torch.utils.information import DataLoader
def train_model():
# Load dataset
full_dataset = load_dataset("stanfordnlp/imdb", break up="prepare")
dataset = full_dataset.shuffle(seed=42).choose(vary(10000))
model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
mannequin = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
optimizer = torch.optim.AdamW(mannequin.parameters(), lr=2e-5)
# Use GPU if out there
gadget = torch.gadget("cuda" if torch.cuda.is_available() else "cpu")
mannequin.to(gadget)
mannequin.prepare()
# Create a DataLoader for batching
dataloader = DataLoader(dataset, batch_size=8, shuffle=True)
# Coaching loop
num_epochs = 3 # Set the variety of epochs
for epoch in vary(num_epochs):
total_loss = 0
for batch in dataloader:
inputs = tokenizer(batch["text"], truncation=True, padding=True, return_tensors="pt", max_length=512).to(gadget)
labels = torch.tensor(batch["label"]).to(gadget)
optimizer.zero_grad()
outputs = mannequin(**inputs, labels=labels)
loss = outputs.loss
loss.backward()
optimizer.step()
total_loss += loss.merchandise()
avg_loss = total_loss / len(dataloader)
print(f"Epoch {epoch + 1}/{num_epochs}, Loss: {avg_loss:.4f}")
# Save the mannequin
mannequin.save_pretrained("./mannequin/")
tokenizer.save_pretrained("./mannequin/")
# Take a look at the mannequin with pattern sentences
test_sentences = [
"This movie was fantastic!",
"I absolutely hated this film.",
"It was just okay, not great.",
"An absolute masterpiece!",
"Waste of time!",
"A beautiful story and well acted.",
"Not my type of movie.",
"It could have been better.",
"A thrilling adventure from start to finish!",
"Very disappointing."
]
# Swap mannequin to analysis mode
mannequin.eval()
# Put together tokenizer for take a look at inputs
inputs = tokenizer(test_sentences, truncation=True, padding=True, return_tensors="pt", max_length=512).to(gadget)
with torch.no_grad():
outputs = mannequin(**inputs)
predictions = torch.argmax(outputs.logits, dim=1)
# Print predictions
for sentence, prediction in zip(test_sentences, predictions):
sentiment = "optimistic" if prediction.merchandise() == 1 else "detrimental"
print(f"Enter: "{sentence}" -> Predicted sentiment: {sentiment}")
# Name the perform to coach the mannequin and take a look at it
train_model()
To be sure that we will question our new mannequin that we now have skilled we now have to replace a couple of of our present recordsdata. For example, in most important.py
we now use the mannequin from ./mannequin
and cargo it as a pretrained mannequin. Moreover, for comparability’s sake, we add now have two endpoints to make use of, /predict/naive
and predict/skilled
.
# Filename: most important.pyfrom fastapi import FastAPI
from pydantic import BaseModel
from transformers import AutoModelForSequenceClassification, AutoTokenizer
from transformers import pipeline
from prometheus_client import Counter, Histogram, start_http_server
import time
# Begin prometheus metrics server on port 8001
start_http_server(8001)
app = FastAPI()
# Load the skilled mannequin and tokenizer from the native listing
model_path = "./mannequin" # Path to your saved mannequin
tokenizer = AutoTokenizer.from_pretrained(model_path)
trained_model = AutoModelForSequenceClassification.from_pretrained(model_path)
# Create pipelines
naive_classifier = pipeline("sentiment-analysis", gadget=-1)
trained_classifier = pipeline("sentiment-analysis", mannequin=trained_model, tokenizer=tokenizer, gadget=-1)
# Metrics
PREDICTION_TIME = Histogram('prediction_duration_seconds', 'Time spent processing prediction')
REQUESTS = Counter('prediction_requests_total', 'Complete requests')
SENTIMENT_SCORE = Histogram('sentiment_score', 'Histogram of sentiment scores', buckets=[0.0, 0.25, 0.5, 0.75, 1.0])
class TextInput(BaseModel):
textual content: str
class SentimentOutput(BaseModel):
textual content: str
sentiment: str
rating: float
@app.submit("/predict/naive", response_model=SentimentOutput)
async def predict_naive_sentiment(input_data: TextInput):
REQUESTS.inc()
start_time = time.time()
end result = naive_classifier(input_data.textual content)[0]
rating = end result["score"]
SENTIMENT_SCORE.observe(rating) # Document the sentiment rating
PREDICTION_TIME.observe(time.time() - start_time)
return SentimentOutput(
textual content=input_data.textual content,
sentiment=end result["label"],
rating=rating
)
@app.submit("/predict/skilled", response_model=SentimentOutput)
async def predict_trained_sentiment(input_data: TextInput):
REQUESTS.inc()
start_time = time.time()
end result = trained_classifier(input_data.textual content)[0]
rating = end result["score"]
SENTIMENT_SCORE.observe(rating) # Document the sentiment rating
We additionally should replace our Dockerfile to incorporate our mannequin recordsdata.
# Filename: Dockerfile
FROM python:3.9-slimWORKDIR /app
COPY necessities.txt .
RUN pip set up -r necessities.txt
COPY most important.py .
COPY ./mannequin ./mannequin
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Importantly, if you’re utilizing git, just be sure you add the pytorch_model.bin
file to git lfs, so that you could push to GitHub. git lfs permits you to use model management on very massive recordsdata.