Verwendung eines benutzerdefinierten Modells
Obwohl der Prozess der Erstellung und Feinabstimmung eines Modells nicht die Absicht dieses Projekts ist, ist es wichtig zu verstehen, wie ein Modell zu diesem Prozess hinzugefügt werden kann.
# Filename: practice.pyimport torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from datasets import load_dataset
from torch.utils.knowledge import DataLoader
def train_model():
# Load dataset
full_dataset = load_dataset("stanfordnlp/imdb", cut up="practice")
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 accessible
system = torch.system("cuda" if torch.cuda.is_available() else "cpu")
mannequin.to(system)
mannequin.practice()
# 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("textual content"), truncation=True, padding=True, return_tensors="pt", max_length=512).to(system)
labels = torch.tensor(batch("label")).to(system)
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/")
# Check the mannequin with pattern sentences
test_sentences = (
"This film was improbable!",
"I completely hated this movie.",
"It was simply okay, not nice.",
"An absolute masterpiece!",
"Waste of time!",
"A phenomenal story and nicely acted.",
"Not my kind of film.",
"It may have been higher.",
"An exhilarating journey from begin to end!",
"Very disappointing."
)
# Change mannequin to analysis mode
mannequin.eval()
# Put together tokenizer for check inputs
inputs = tokenizer(test_sentences, truncation=True, padding=True, return_tensors="pt", max_length=512).to(system)
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 "unfavourable"
print(f"Enter: "{sentence}" -> Predicted sentiment: {sentiment}")
# Name the perform to coach the mannequin and check it
train_model()
Um sicherzustellen, dass wir unser neues, trainiertes Modell abfragen können, müssen wir einige unserer vorhandenen Dateien aktualisieren. Zum Beispiel in essential.py
Wir verwenden jetzt das Modell von ./mannequin
und laden Sie es als vorab trainiertes Modell. Zum Vergleich fügen wir außerdem hinzu, dass jetzt zwei Endpunkte verwendet werden müssen: /predict/naive
Und predict/skilled
.
# Filename: essential.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", system=-1)
trained_classifier = pipeline("sentiment-analysis", mannequin=trained_model, tokenizer=tokenizer, system=-1)
# Metrics
PREDICTION_TIME = Histogram('prediction_duration_seconds', 'Time spent processing prediction')
REQUESTS = Counter('prediction_requests_total', 'Whole 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.publish("/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("rating")
SENTIMENT_SCORE.observe(rating) # File 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.publish("/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("rating")
SENTIMENT_SCORE.observe(rating) # File the sentiment rating
Wir müssen auch unsere Docker-Datei aktualisieren, um unsere Modelldateien einzuschließen.
# Filename: Dockerfile
FROM python:3.9-slimWORKDIR /app
COPY necessities.txt .
RUN pip set up -r necessities.txt
COPY essential.py .
COPY ./mannequin ./mannequin
CMD ("uvicorn", "essential:app", "--host", "0.0.0.0", "--port", "8000")
Wichtig: Wenn Sie Git verwenden, stellen Sie sicher, dass Sie Folgendes hinzufügen pytorch_model.bin
Datei an git lfsdamit Sie auf GitHub pushen können. Mit git lfs können Sie die Versionskontrolle für sehr große Dateien verwenden.