Tour the Hugging Face Ecosystem
Build and deploy a live sentiment analysis app using Hugging Face tools.
Introduction
30 Second Summary
AI models are more accessible than ever, but the ecosystem around them can feel overwhelming. There are platforms for finding models, libraries for running them, APIs for calling them remotely, and tools for deploying them as apps.
In this project, you will build a sentiment analysis web app that touches four core Hugging Face products. You will go from running a model locally to deploying a live app anyone can use.
What You'll Build
A sentiment analysis web application that classifies text as positive or negative using DistilBERT, deployed live on Hugging Face Spaces for anyone to access.
By the end of this project, you'll have:
- A Python script that runs sentiment analysis locally using the Transformers pipeline.
- A script that calls models remotely via the Inference Providers API without downloading anything.
- A polished Gradio web app deployed live on Hugging Face Spaces with a public URL you can share with anyone.
- Secret Mission: Extend your app with multi-task analysis combining sentiment, summarization, and zero-shot classification into one powerful interface.
Are there any prerequisites?
You need basic Python knowledge and a free Hugging Face account. If you do not have an account yet, you will create one in Step 1.
Set Up Your Python Environment
Before you can run AI models, you need a working Python environment with the right packages installed. Without this foundation, none of the code in later steps will run.
In this step, you'll create a dedicated project folder, install the four Python libraries that power the Hugging Face ecosystem, and set up an access token so you can call models remotely.
In this step, get ready to:
- Open VS Code and create your project folder.
- Install the Python packages for this project.
- Create a Hugging Face account and set up your access token.
Open VS Code and create your project folder
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Visual Studio Code and press Enter to open it.
You need a terminal inside VS Code to run commands. VS Code has one built in.
- Open the integrated terminal by pressing Ctrl+` (macOS and Windows). This is the backtick key, usually above Tab.
Now create a dedicated folder for this project on your Desktop so you can find it easily.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and move into it by running these commands:
mkdir hf-ecosystem
cd hf-ecosystem
- Open this folder in VS Code by running:
code .
What does this command do?
The code . command tells VS Code to open the current directory as a workspace. Your terminal session stays inside hf-ecosystem, and the Explorer sidebar on the left now shows this folder.
- If VS Code opens a new window, open the integrated terminal again with Ctrl+`.
- Confirm you are inside the hf-ecosystem folder by running:
pwd
- You should see a path ending in hf-ecosystem, like /Users/yourname/Desktop/hf-ecosystem.
code . not recognized?
- On macOS, open the VS Code Command Palette with Cmd+Shift+P, type shell command, and select Shell Command: Install 'code' command in PATH. Then close and reopen your terminal.
- On Windows, the code command is added to PATH during VS Code installation. If it is not found, reinstall VS Code and check the Add to PATH option during setup.
Help me set up the code command in my terminal.
Check your Python version
This project requires Python 3.10 or higher. The packages you will install need features introduced in Python 3.10.
- Check your installed Python version by running:
python3 --version
✔️ I see version 3.10 or higher
Your Python version is compatible. You are ready to create a virtual environment in the next substep.
ⓧ I see an older version
You have Python installed, but it is below 3.10. On macOS, the system Python is often an older version that ships with the OS.
- Install the latest Python from python.org/downloads.
- Run the installer and follow the prompts.
- After installation, close and reopen your terminal, then run python3 --version again to confirm it shows 3.10 or higher.
Why might my version still show the old one?
On macOS, the system python3 can still point to the older version after installing a new one. If you installed Python 3.12, try running python3.12 --version to verify it is available. You can use python3.12 in place of python3 for the rest of this project.
ⓧ Command not found
Python is not installed on your machine yet.
- Go to python.org/downloads and download the latest Python installer for your operating system.
- Run the installer. On Windows, check the Add python.exe to PATH checkbox before clicking Install Now.
- After installation, close and reopen your terminal in VS Code.
- Run python3 --version (macOS/Linux) or python --version (Windows) to confirm you see 3.10 or higher.
Create a virtual environment and install packages
A virtual environment keeps this project's packages separate from other Python projects on your machine. This prevents version conflicts between projects.
- Create a virtual environment by running:
python3 -m venv venv
What does this command do?
python3 -m venv venv creates a self-contained Python environment inside a folder called venv in your project directory. When activated, any packages you install go into this folder instead of your system Python.
- Activate the virtual environment:
macOS
source venv/bin/activate
Windows
venv\Scripts\activate
Linux
source venv/bin/activate
- You should see (venv) appear at the beginning of your terminal prompt. This confirms the virtual environment is active.
Not seeing (venv) in your prompt?
- On Windows, if you see an error about execution policies, run Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned first, then try the activate command again.
- Make sure you are in the hf-ecosystem folder. Run pwd to check. The venv folder must be in the same directory where you run the activate command.
Help me activate my Python virtual environment.
Now install all four packages you need for this project.
- Install the project dependencies by running:
pip install transformers torch datasets huggingface_hub gradio
What are these packages?
- transformers — the main library for loading and running AI models locally.
- torch — the deep learning framework that powers model inference behind the scenes.
- datasets — for loading and exploring datasets from the Hugging Face Hub.
- huggingface_hub — for calling models remotely via the Inference Providers API.
- gradio — for building web interfaces around your models.
- Wait for the installation to finish. This downloads several large packages (especially torch) and may take a few minutes depending on your internet speed.
- You should see Successfully installed followed by a list of package names at the end of the output.
Installation failing?
- If you see a permissions error, make sure your virtual environment is activated. You should see (venv) in your terminal prompt.
- If the download is slow or times out, try running the install command again. pip will resume where it left off.
- If you see a Python version error, confirm you are using Python 3.10 or higher inside the venv by running python --version.
Help me fix my pip install errors.
Create a Hugging Face account and set your access token
Later in this project, you will call models remotely via the Inference Providers API. This requires a free Hugging Face account and an access token to authenticate your requests.
- Go to huggingface.co/join in your browser.
- Create a free account (or sign in if you already have one).
- Once logged in, go to huggingface.co/settings/tokens.
- Click Create new token.
- Give your token a name like nextwork-project.
- Select Read for the token type.
- Click Create token.
- Copy the token value. You will only see it once.
Why do I need a token?
The access token proves your identity when calling models via the API. It is free and gives you access to thousands of models. You will use this token in Step 3 when you call models remotely using InferenceClient.
Now set the token as an environment variable in your terminal so your scripts can read it.
- In your VS Code terminal, set the HF_TOKEN environment variable:
macOS
export HF_TOKEN=your-token-here
Windows
$env:HF_TOKEN = "your-token-here"
Linux
export HF_TOKEN=your-token-here
Replace the placeholder with your actual token
Replace your-token-here with the token you just copied from the Hugging Face settings page. On macOS/Linux, paste the token directly with no quotes. On Windows PowerShell, keep the quotes and paste your token between them.
- Verify the token is set correctly by running:
macOS
echo $HF_TOKEN
Windows
echo $env:HF_TOKEN
Linux
echo $HF_TOKEN
- You should see your token value printed in the terminal. If it prints nothing or shows the literal text your-token-here, re-run the export command with your actual token.
This token is session-only
The export (macOS/Linux) or $env: (Windows PowerShell) command only sets the variable for your current terminal session. If you close and reopen your terminal, you will need to set it again before running scripts that use the API.
Your environment is ready with all packages installed and your Hugging Face token set. Next up, you'll push this project to GitHub so you have a shareable link from day one.
Push Your Project to GitHub
Your Python environment is ready with all packages installed and your Hugging Face token set. Before you start writing code, there's one more thing to set up.
In this step, you'll create a GitHub repository for your project. This gives you a public link you can share with potential employers to show the AI work you've done.
In this step, get ready to:
- Confirm Git is installed on your machine.
- Initialize a Git repository with a .gitignore file.
- Create a GitHub repository and push your first commit.
Check that Git is installed
Git is a version control tool that tracks changes to your files. GitHub hosts your Git repository online so others can see your work.
- Check your Git version by running this command in your VS Code terminal:
git --version
✔️ I see a version number
Git is installed and ready. You can move on to initializing your repository.
ⓧ Command not found
Git is not installed on your machine yet.
- Go to git-scm.com/downloads and download the installer for your operating system.
- Run the installer and accept the default options.
- Close and reopen your terminal in VS Code, then run git --version again to confirm it shows a version number.
Initialize your Git repository
Before tracking changes, you need to tell Git which files to ignore. Your venv folder and Python cache files are machine-specific and should not be uploaded to GitHub.
- Create a .gitignore file by running this command:
echo "venv/\n__pycache__/\n.env" > .gitignore
What is a .gitignore file?
A .gitignore file tells Git which files and folders to skip when tracking changes. The venv/ folder contains thousands of library files that anyone can reinstall with pip install, so there's no need to upload them.
- Initialize your Git repository and make your first commit by running these commands:
git init
git add .
git commit -m "Initial commit: project setup with .gitignore"
What do these commands do?
- git init creates a new Git repository in your current folder.
- git add . stages all files (except those in .gitignore) for your first commit.
- git commit -m "..." saves a snapshot of your project with a descriptive message.
- You should see output showing files committed, including .gitignore. The venv/ folder should not appear in the list.
Seeing 'Author identity unknown'?
Git needs your name and email to label commits. Run these two commands, replacing the placeholders with your own details:
git config --global user.email "your-email@example.com"
git config --global user.name "Your Name"
Then run the git commit command again.
Help me configure Git on my machine.
Create a GitHub repository and push your code
Now you'll create a repository on GitHub and push your local project to it. This makes your code visible online at a URL you can share.
- Go to github.com/new in your browser. Sign in or create a free account if you don't have one.
- Enter hf-ecosystem as the Repository name.
- Leave the repository set to Public so potential employers can see it.
- Do not check any boxes for README, .gitignore, or license. You already have a local repository.
- Click Create repository.
GitHub shows a quick setup page with commands. You'll use the commands for pushing an existing repository.
- Back in your VS Code terminal, connect your local repository to GitHub by running these commands:
git branch -M main
git remote add origin https://github.com/[[GITHUB_USERNAME="your GitHub username"]]/hf-ecosystem.git
git push -u origin main
What do these commands do?
- git branch -M main renames your default branch to main (the GitHub standard).
- git remote add origin links your local repository to the GitHub repository you just created.
- git push -u origin main uploads your commit to GitHub. The -u flag sets this as the default remote so future pushes only need git push.
- If prompted to authenticate, sign in with your GitHub credentials. On macOS you may see a browser pop-up. On Windows, a credential manager window may appear.
Authentication failed?
- GitHub no longer accepts passwords for Git operations. If you see an authentication error, you need to use a Personal Access Token or sign in via browser.
- Go to github.com/settings/tokens, generate a new token with repo scope, and use it as your password when prompted.
Help me authenticate Git with GitHub.
- Refresh your GitHub repository page in the browser. You should see your .gitignore file listed.
Commit after each step
As you build scripts in later steps, commit your progress regularly. A repository with multiple commits shows employers how you approached the project step by step.
Your project now has a public GitHub home that you can share with anyone. Next up, you'll explore the Hugging Face Model Hub and run your first AI model locally.
Explore the Hub and Run Your First Pipeline
Your project is set up with a working Python environment and a public GitHub repository. Now it's time to actually use the tools you installed.
In this step, you'll explore the Hugging Face Hub to understand how models are organized, then run a pre-trained sentiment analysis model on your own machine using just a few lines of Python.
In this step, get ready to:
- Explore the Hugging Face Model Hub and find the DistilBERT sentiment analysis model.
- Create a Python script that runs sentiment analysis locally using the Transformers pipeline.
- Analyze multiple texts and observe how the model returns confidence scores.
Navigate the Hugging Face Model Hub
The Hugging Face Hub hosts over 2 million models, organized by task. Before writing any code, take a quick tour so you know how to find models for any project.
- Open your browser and go to huggingface.co/models.
- Click Add filters near the top of the page.
- Select the Tasks tab in the filter panel.
- Browse the available task categories like Text Generation, Text Classification, and Image-to-Text.
- Close the filter panel for now.
What is the Model Hub?
The Model Hub is a searchable directory of pre-trained models contributed by the community. Each model has a model card with documentation, usage examples, performance metrics, and an interactive widget you can test right in the browser.
Filtering by task lets you find models purpose-built for what you need, whether that's text classification, translation, image generation, or dozens of other tasks.
Now navigate directly to the model you'll use in this project.
- Go to huggingface.co/distilbert/distilbert-base-uncased-finetuned-sst-2-english.
- Read through the model card to see what the model does, what dataset it was trained on, and its accuracy.
- Notice the task label at the top of the card showing Text Classification.
Why this model?
DistilBERT is a lightweight version of BERT with 67 million parameters. This particular version was fine-tuned on the SST-2 sentiment dataset, achieving 91.3% accuracy.
It runs fast on CPU, produces clear POSITIVE/NEGATIVE results with confidence scores, and is the default model for the Transformers sentiment-analysis pipeline.
Create your pipeline script
The Transformers library has a concept called a pipeline that wraps a model, tokenizer, and post-processing into a single callable function. You give it text, it gives you predictions.
- In the VS Code Explorer sidebar on the left, right-click in the empty space below your folder name.
- Select New File from the context menu.
- Type explore_pipeline.py and press Enter.
- The file opens in the editor and is immediately saved to disk inside your hf-ecosystem folder.
- Add the import and pipeline setup by pasting this code:
from transformers import pipeline
# Create a sentiment analysis pipeline with a specific model
classifier = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
What does this code do?
- pipeline("sentiment-analysis", ...) creates a ready-to-use sentiment classifier.
- The model parameter tells it exactly which pre-trained model to download from the Hub.
- Behind the scenes, pipeline() downloads the model weights, loads the tokenizer, and sets up the inference machinery.
- Add the single-text analysis below the pipeline setup:
# Analyze a single text
result = classifier("I love learning about AI and machine learning!")
print("Single text result:")
print(result)
print()
What does this code do?
- classifier("...") passes your text through the model and returns a list of dictionaries.
- Each dictionary contains a label (POSITIVE or NEGATIVE) and a score (confidence between 0 and 1).
- Add the batch analysis code at the bottom of the file:
# Analyze multiple texts
texts = [
"This movie was absolutely fantastic!",
"I'm really disappointed with the service.",
"The food was okay, nothing special.",
]
results = classifier(texts)
print("Batch results:")
for text, result in zip(texts, results):
print(f"Text: {text}")
print(f" Sentiment: {result['label']} (confidence: {result['score']:.4f})")
print()
What does this code do?
- Passing a list of strings to classifier(texts) runs batch inference, processing all three at once.
- The zip() pairs each original text with its result for clean printing.
- The :.4f format shows confidence to 4 decimal places, so you can see exactly how sure the model is.
- Save explore_pipeline.py.
✔️ Awesome, I've got everything!
Great. Double check you've saved your file before running it.
ⓧ I'd like to double check the full code
Here is the complete explore_pipeline.py file:
from transformers import pipeline
# Create a sentiment analysis pipeline with a specific model
classifier = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
# Analyze a single text
result = classifier("I love learning about AI and machine learning!")
print("Single text result:")
print(result)
print()
# Analyze multiple texts
texts = [
"This movie was absolutely fantastic!",
"I'm really disappointed with the service.",
"The food was okay, nothing special.",
]
results = classifier(texts)
print("Batch results:")
for text, result in zip(texts, results):
print(f"Text: {text}")
print(f" Sentiment: {result['label']} (confidence: {result['score']:.4f})")
print()
Run the script and observe the results
Time to see the model in action. The first run downloads the model weights from the Hub, which may take a moment.
- Run your script by executing this command in your terminal:
python explore_pipeline.py
- Wait for the model to download (about 250 MB on the first run).
- You should see output showing the single text result followed by the batch results.
What should I see?
Your output will look something like this:
Single text result:
[{'label': 'POSITIVE', 'score': 0.9998}]
Batch results:
Text: This movie was absolutely fantastic!
Sentiment: POSITIVE (confidence: 0.9999)
Text: I'm really disappointed with the service.
Sentiment: NEGATIVE (confidence: 0.9998)
Text: The food was okay, nothing special.
Sentiment: NEGATIVE (confidence: 0.9467)
Notice how the model is very confident about clearly positive or negative statements. The neutral-sounding text ("okay, nothing special") gets a lower confidence score because the model is less certain.
🙋♀️ Seeing an error when running the script?
- If you see a ModuleNotFoundError, make sure you installed transformers and torch in Step 1.
- If the download seems stuck, check your internet connection. The model is about 250 MB.
- If you see a timeout error, try running the command again. The Hub occasionally has brief delays during peak usage.
Help me debug my Transformers pipeline script
🙋♀️ Seeing No such file or directory?
- This means explore_pipeline.py does not exist on disk in your current folder. Even if the file appears open in VS Code, it may not be saved yet.
- Press Ctrl+S (Windows/Linux) or Cmd+S (macOS) to save the file. If VS Code asks where to save it, choose your hf-ecosystem folder and name it explore_pipeline.py.
- Confirm the file exists by running ls (macOS/Linux) or dir (Windows) in your terminal. You should see explore_pipeline.py listed in the output.
- If you used File > New File from the top menu instead of right-clicking in the Explorer sidebar, VS Code may have created an untitled file. Use Ctrl+Shift+S (Save As) to save it as explore_pipeline.py inside your hf-ecosystem folder.
Help me fix the file not found error when running my Python script.
You just ran a pre-trained AI model on your own machine with 6 lines of setup code. Next up, you'll load a real dataset and see how the model performs on movie reviews.
Load and Explore a Dataset
Your sentiment pipeline works on hand-written text, but how does it perform on real-world data? The Hugging Face ecosystem includes a Datasets library with thousands of ready-to-use datasets for machine learning tasks.
In this step, you'll load the IMDB movie review dataset and test your model against reviews that were labeled by humans. This is how ML engineers validate whether a model actually works in practice.
In this step, get ready to:
- Load the IMDB dataset using the Datasets library.
- Explore the dataset structure and print sample reviews.
- Compare your model's predictions to human-labeled answers.
Load the IMDB movie review dataset
The IMDB dataset contains 50,000 movie reviews labeled as positive or negative. You'll load a small slice of 10 reviews to keep things fast.
- In VS Code, click File then New File.
- Name the file explore_datasets.py and press Enter. You should see it appear in the Explorer sidebar alongside explore_pipeline.py.
- Add the following imports and dataset loading code:
from datasets import load_dataset
from transformers import pipeline
# Load a small slice of the IMDB dataset
dataset = load_dataset("stanfordnlp/imdb", split="test[:10]")
What does this code do?
The load_dataset function fetches datasets directly from the Hugging Face Hub. The "stanfordnlp/imdb" argument is the dataset's full name on the Hub, using the owner/dataset-name format (just like GitHub repositories).
The split="test[:10]" parameter loads only the first 10 examples from the test split. This keeps download times short while giving you enough data to explore.
- Save explore_datasets.py.
You won't see any output yet. The next section adds print statements to explore what you loaded.
Explore the dataset structure and print sample reviews
Before running your model on this data, it helps to understand what the dataset looks like. Each example has a text field (the review) and a label field (0 for negative, 1 for positive).
- In explore_datasets.py, add this code below the load_dataset line:
# Explore the dataset structure
print(f"Dataset: {dataset}")
print(f"Features: {dataset.features}")
print(f"Number of examples: {len(dataset)}")
print()
# Look at a few examples
for i in range(3):
example = dataset[i]
label = "Positive" if example["label"] == 1 else "Negative"
print(f"Review {i+1} ({label}):")
print(f" {example['text'][:200]}...")
print()
What does this code do?
- The first three print statements show the dataset's structure: what type it is, what columns (features) it has, and how many rows it contains.
- The for loop prints the first 3 reviews with their human-assigned label. Each review is truncated to 200 characters so it fits on screen.
- The label mapping converts the numeric 0/1 values into readable "Positive" or "Negative" strings.
- Save explore_datasets.py.
- Run the script by executing this command in your terminal:
python explore_datasets.py
- You should see the dataset metadata (features and number of examples) followed by 3 movie reviews with their sentiment labels.
Seeing an HfUriError or download error?
The first time you run this script, the Datasets library downloads the IMDB data from the Hub. You'll see progress bars in your terminal. On subsequent runs, it loads from your local cache instantly.
- If you see HfUriError: Repository id must be 'namespace/name', make sure your code uses the full dataset path "stanfordnlp/imdb" (not just "imdb"). Hugging Face now requires the full owner/name format.
- If you see a network error, check your internet connection. The dataset needs to download from the Hugging Face Hub on first run.
- Make sure you installed the datasets package in Step 1. If not, run pip install datasets again.
Why can't I load the IMDB dataset?
Compare model predictions to actual labels
Now for the interesting part. You'll run the same sentiment pipeline from the previous step on these reviews and check whether the model agrees with the human labels.
- In explore_datasets.py, add this code at the bottom of your file:
# Run sentiment analysis on dataset samples
classifier = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print("Model predictions vs actual labels:")
for i in range(5):
example = dataset[i]
actual = "POSITIVE" if example["label"] == 1 else "NEGATIVE"
# Truncate to 512 chars for the model
prediction = classifier(example["text"][:512])[0]
match = "\u2713" if prediction["label"] == actual else "\u2717"
print(f" {match} Actual: {actual} | Predicted: {prediction['label']} ({prediction['score']:.4f})")
What does this code do?
- It creates the same sentiment analysis pipeline you used in the previous step, using the same DistilBERT model.
- The loop runs predictions on 5 reviews and compares each model prediction to the actual human label.
- Reviews are truncated to 512 characters because the model has a maximum input length.
- A checkmark means the model agreed with the human label. An X means it disagreed.
✔️ Awesome, I've got everything!
Great. Double check you've saved your file before moving on.
ⓧ I'd like to double check the full code
Here's the complete explore_datasets.py file so far:
from datasets import load_dataset
from transformers import pipeline
# Load a small slice of the IMDB dataset
dataset = load_dataset("stanfordnlp/imdb", split="test[:10]")
# Explore the dataset structure
print(f"Dataset: {dataset}")
print(f"Features: {dataset.features}")
print(f"Number of examples: {len(dataset)}")
print()
# Look at a few examples
for i in range(3):
example = dataset[i]
label = "Positive" if example["label"] == 1 else "Negative"
print(f"Review {i+1} ({label}):")
print(f" {example['text'][:200]}...")
print()
# Run sentiment analysis on dataset samples
classifier = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print("Model predictions vs actual labels:")
for i in range(5):
example = dataset[i]
actual = "POSITIVE" if example["label"] == 1 else "NEGATIVE"
# Truncate to 512 chars for the model
prediction = classifier(example["text"][:512])[0]
match = "\u2713" if prediction["label"] == actual else "\u2717"
print(f" {match} Actual: {actual} | Predicted: {prediction['label']} ({prediction['score']:.4f})")
- Save explore_datasets.py.
- Run the script again:
python explore_datasets.py
- You should see the dataset exploration output followed by a comparison table showing how the model's predictions line up against the actual labels.
Why does the model sometimes get it wrong?
No model is perfect. DistilBERT was fine-tuned on movie reviews from SST-2 (a different dataset), so it does well on IMDB reviews. However, sarcasm, mixed sentiments, and ambiguous phrasing can trip it up.
🙋♀️ Seeing mostly X marks?
- Double-check the label mapping in the comparison section. The IMDB dataset uses 1 for positive and 0 for negative.
- Make sure your actual label maps to "POSITIVE" (uppercase) to match the model's output format.
Why are my model predictions not matching the labels?
You've now loaded real ML data and validated your model's predictions against human labels. Next, you'll call models remotely via the Inference Providers API, so you can use models without downloading them at all.
Call Models via the Inference Providers API
In the last step, you loaded a real dataset and compared your model's predictions to actual labels. Now you'll explore a completely different way to use models.
Instead of downloading a model to your machine, the Hugging Face Inference Providers API lets you call models remotely over the internet. This means faster setup and zero local storage costs.
In this step, get ready to:
- Call the sentiment analysis model remotely using InferenceClient.
- Compare local inference to API-based inference.
- Call a text generation model to see how the API works across tasks.
Create inference_api.py and connect to the Inference Providers API
The InferenceClient class from the huggingface_hub library sends your text to a model running on Hugging Face's servers. You get back the same predictions without needing to download the model files.
- In VS Code, click File then New File.
- Name the file inference_api.py and press Enter.
- Add the following code to set up InferenceClient and classify a single text remotely:
import os
from huggingface_hub import InferenceClient
# Initialize the client with your HF token
client = InferenceClient(api_key=os.environ["HF_TOKEN"])
# Use text classification via Inference Providers
print("=== Sentiment Analysis via Inference API ===")
result = client.text_classification(
"I love using open source AI models!",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print(f"Result: {result}")
print()
What does this code do?
- InferenceClient(api_key=os.environ["HF_TOKEN"]) creates an API client authenticated with your Hugging Face token. The client reads the token from the HF_TOKEN environment variable you set earlier.
- client.text_classification(...) sends your text to the model running remotely and returns a list of TextClassificationOutputElement objects with label and score fields.
- You specify the same distilbert/distilbert-base-uncased-finetuned-sst-2-english model you used locally. The API automatically routes to the fastest available provider.
- Save inference_api.py.
- Run the script by entering this command in your terminal:
python inference_api.py
You should see a result showing POSITIVE with a high confidence score, similar to what you got with the local pipeline.
Seeing an authentication error?
- Make sure the HF_TOKEN environment variable is set in your current terminal session. You can verify by running echo $HF_TOKEN (macOS/Linux) or echo $env:HF_TOKEN (Windows PowerShell). If it prints nothing, re-set the variable.
- On Windows, make sure you used PowerShell syntax: $env:HF_TOKEN = "your-token". The Command Prompt syntax set HF_TOKEN=... does not work in PowerShell.
- Confirm your token has at least read access. You can check your tokens at huggingface.co/settings/tokens.
Help me fix my HF_TOKEN authentication error when using InferenceClient.
Now add batch analysis to classify multiple texts in a loop.
- Add the following code below the existing code in inference_api.py:
# Try multiple texts
texts = [
"This is amazing, I'm so happy!",
"I'm feeling terrible today.",
"The meeting is at 3pm tomorrow.",
]
print("=== Batch Analysis ===")
for text in texts:
result = client.text_classification(
text,
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print(f"Text: {text}")
print(f" Top result: {result[0]}")
print()
What does this code do?
This loops through three texts and classifies each one via the API. Notice result[0] grabs the top prediction. The API returns a ranked list of all possible labels, so index 0 is the highest-confidence prediction.
The third sentence ("The meeting is at 3pm tomorrow.") is intentionally neutral. Watch how the model handles text that is not clearly positive or negative.
- Save inference_api.py and run it again:
python inference_api.py
You should see each text classified with POSITIVE or NEGATIVE and a confidence score. The neutral sentence will still get a label, but with a lower confidence.
Getting a timeout or 503 error?
The model might be loading on the server. Wait 30 seconds and try again. Inference Providers sometimes need a moment to spin up a model that has not been used recently.
Help me fix a timeout error when calling models via the Hugging Face Inference API.
Compare local vs. API inference
You have now used the same model two ways: locally in explore_pipeline.py and remotely in inference_api.py. Both return POSITIVE or NEGATIVE with confidence scores. The results are equivalent because it is the same model.
Why use the API instead of local inference?
Local inference downloads the full model to your machine. This gives you offline access and full control, but uses disk space and RAM. It works best when you need low latency or run many predictions in a batch.
The Inference Providers API runs models on remote servers. You never download model files. This is ideal for quick prototyping, accessing larger models that would not fit on your machine, or building apps where you want to avoid bundling model weights.
In the next step, you will build a Gradio app that uses local inference. For production apps that need to stay lightweight, you could swap in the API with just a few lines changed.
✔️ I'll skip text generation
No problem. The text classification calls already proved the concept of calling models remotely. Save inference_api.py and move on to the next step.
Here's the complete inference_api.py file for reference:
import os
from huggingface_hub import InferenceClient
# Initialize the client with your HF token
client = InferenceClient(api_key=os.environ["HF_TOKEN"])
# Use text classification via Inference Providers
print("=== Sentiment Analysis via Inference API ===")
result = client.text_classification(
"I love using open source AI models!",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print(f"Result: {result}")
print()
# Try multiple texts
texts = [
"This is amazing, I'm so happy!",
"I'm feeling terrible today.",
"The meeting is at 3pm tomorrow.",
]
print("=== Batch Analysis ===")
for text in texts:
result = client.text_classification(
text,
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print(f"Text: {text}")
print(f" Top result: {result[0]}")
print()
ⓧ I'd like to try text generation too
The InferenceClient is not limited to classification. You can also call text generation models using the same client. This demonstrates how one client can access many different model types on the Hub.
Need to enable inference providers first
Chat completion models require an inference provider to be enabled on your account. Before running this code, go to huggingface.co/settings/inference-providers and make sure at least one provider is enabled (such as Novita, Cerebras, or Together).
Free accounts receive $0.10 in monthly credits (no payment required). This is enough for the single API call below.
- Add the following code to the bottom of inference_api.py:
# Demonstrate text generation with a different model
print("=== Text Generation via Inference API ===")
completion = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "Explain sentiment analysis in one sentence."}],
max_tokens=50,
)
print(f"Generated: {completion.choices[0].message.content}")
What does this code do?
client.chat.completions.create(...) calls a text generation model using the OpenAI-compatible chat format. You pass a list of messages and get back a generated response.
The model Qwen/Qwen2.5-7B-Instruct is a 7-billion parameter instruction-tuned chat model. Running this locally would require significant GPU memory. With the API, you access it instantly without downloading anything.
- Save inference_api.py and run it one more time:
python inference_api.py
You should see all three sections print: the single classification, the batch analysis, and a generated sentence explaining sentiment analysis.
Seeing 'model not supported by any provider'?
- This error means you do not have a chat completion provider enabled. Go to huggingface.co/settings/inference-providers and enable at least one provider that supports chat completion (such as Novita, Cerebras, or Together).
- Make sure your HF token has the Inference Providers permission. You can check this at huggingface.co/settings/tokens.
- If you have exhausted your free credits ($0.10/month for free accounts), you will need to wait for the next billing cycle or purchase additional credits.
Help me fix a 'model not supported by any provider' error when calling chat.completions.create via the Hugging Face Inference API.
Here is the complete inference_api.py file with text generation included:
import os
from huggingface_hub import InferenceClient
# Initialize the client with your HF token
client = InferenceClient(api_key=os.environ["HF_TOKEN"])
# Use text classification via Inference Providers
print("=== Sentiment Analysis via Inference API ===")
result = client.text_classification(
"I love using open source AI models!",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print(f"Result: {result}")
print()
# Try multiple texts
texts = [
"This is amazing, I'm so happy!",
"I'm feeling terrible today.",
"The meeting is at 3pm tomorrow.",
]
print("=== Batch Analysis ===")
for text in texts:
result = client.text_classification(
text,
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
print(f"Text: {text}")
print(f" Top result: {result[0]}")
print()
# Demonstrate text generation with a different model
print("=== Text Generation via Inference API ===")
completion = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "Explain sentiment analysis in one sentence."}],
max_tokens=50,
)
print(f"Generated: {completion.choices[0].message.content}")
You just accessed models remotely without downloading a single weight file. Next up, you will build a web interface around your sentiment analyzer using Gradio and make it interactive.
Build a Gradio Web App
So far, all your scripts have been terminal-only. The results are useful for developers, but you couldn't hand them to a colleague and say "try my sentiment analyzer."
Gradio is a Python library that wraps any function in a web interface with just a few lines of code. In this step, you'll turn your sentiment analysis pipeline into an interactive web app that anyone can use in their browser.
In this step, get ready to:
- Create app.py with a sentiment analysis function.
- Build a Gradio interface with a title, description, and examples.
- Test the app locally in your browser.
Create the sentiment analysis function
Your app needs two things: the same Transformers pipeline you've been using, and a function that formats the results nicely for a web interface.
- In VS Code, click File then New File.
- Name the file app.py and press Enter. You should see it in the Explorer sidebar alongside your other scripts.
- Add the imports and pipeline setup by pasting this code:
import gradio as gr
from transformers import pipeline
# Load the sentiment analysis pipeline
classifier = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
What does this code do?
- import gradio as gr brings in the Gradio library for building web UIs.
- The classifier pipeline loads the same DistilBERT model you used in explore_pipeline.py. Loading it outside the function means the model is ready in memory before any user request arrives.
- You won't see a change yet. Next, you'll add the function that processes user input.
- Below the pipeline code, add the analyze_sentiment function:
def analyze_sentiment(text):
"""Analyze the sentiment of input text."""
if not text.strip():
return "Please enter some text to analyze."
result = classifier(text)[0]
label = result["label"]
score = result["score"]
emoji = "😊" if label == "POSITIVE" else "😞"
return f"{emoji} {label} (confidence: {score:.4f})"
What does this function do?
- It takes a string of text from the user and passes it through the classifier pipeline.
- The if not text.strip() guard returns a helpful message if the user submits empty input.
- It formats the output with an emoji and confidence score so the result is readable at a glance.
- Save app.py. You won't see a visible change yet. The next chunk adds the Gradio interface that uses this function.
Add the Gradio interface with examples
Gradio's gr.Interface connects your function to input and output widgets. You'll also add a title, description, and example inputs so users know exactly what the app does.
- At the bottom of app.py, below the analyze_sentiment function, add the interface configuration and launch block:
demo = gr.Interface(
fn=analyze_sentiment,
inputs=gr.Textbox(
label="Enter text to analyze",
placeholder="Type a sentence here...",
lines=3,
),
outputs=gr.Textbox(label="Sentiment Result"),
title="🤗 Sentiment Analyzer",
description="Analyze the sentiment of any text using DistilBERT, a lightweight transformer model fine-tuned on SST-2. Part of a Hugging Face ecosystem tour!",
examples=[
["I love this product, it works amazingly well!"],
["This is the worst experience I've ever had."],
["The weather today is okay, nothing special."],
],
)
if __name__ == "__main__":
demo.launch()
What does this code do?
- fn=analyze_sentiment tells Gradio which function to call when a user submits text.
- inputs and outputs define the UI widgets. Gradio auto-generates a text box for input and a text box for the result.
- title and description appear at the top of the page so users understand what the app does.
- examples adds clickable sample inputs. Users can click any example to instantly see a result without typing.
- demo.launch() starts a local web server so you can interact with your app in the browser.
- Save app.py.
Seeing a syntax error on save?
- Check that your examples list uses double square brackets. Each example is a list inside the outer list (e.g. ["text"] not just "text").
- Make sure the gr.Interface( call has a matching closing ) after the examples block.
Having trouble with a syntax error?
✔️ Awesome, I've got everything!
Great. Double check you've saved app.py and let's run it.
ⓧ I'd like to double check the full code
Here is the complete app.py at this point:
import gradio as gr
from transformers import pipeline
# Load the sentiment analysis pipeline
classifier = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
def analyze_sentiment(text):
"""Analyze the sentiment of input text."""
if not text.strip():
return "Please enter some text to analyze."
result = classifier(text)[0]
label = result["label"]
score = result["score"]
emoji = "😊" if label == "POSITIVE" else "😞"
return f"{emoji} {label} (confidence: {score:.4f})"
demo = gr.Interface(
fn=analyze_sentiment,
inputs=gr.Textbox(
label="Enter text to analyze",
placeholder="Type a sentence here...",
lines=3,
),
outputs=gr.Textbox(label="Sentiment Result"),
title="🤗 Sentiment Analyzer",
description="Analyze the sentiment of any text using DistilBERT, a lightweight transformer model fine-tuned on SST-2. Part of a Hugging Face ecosystem tour!",
examples=[
["I love this product, it works amazingly well!"],
["This is the worst experience I've ever had."],
["The weather today is okay, nothing special."],
],
)
if __name__ == "__main__":
demo.launch()
Run the app locally and test it
Time to see your app in action. Gradio starts a local web server and gives you a URL to open in your browser.
- Launch your app by running this command in your terminal:
python app.py
What should I see?
After the model loads (this may take a few seconds the first time), Gradio prints a local URL in your terminal. It looks like http://127.0.0.1:7860.
- Open the URL shown in your terminal in your browser.
- Type a sentence in the text box (for example, I love this product, it works amazingly well!) and click **Submit**.
- You should see the sentiment result appear with an emoji, the label (POSITIVE or NEGATIVE), and a confidence score.
- Try clicking one of the example inputs below the text box to test quickly.
App not loading in the browser?
- Make sure you saved app.py before running the command.
- Check your terminal for error messages. An ImportError means Gradio is not installed. Run pip install gradio and try again.
- If the page loads but nothing happens when you click Submit, check that your analyze_sentiment function is defined above the gr.Interface block.
My Gradio app isn't working. Can you help me debug it?
- When you're done testing, press Ctrl+C in your terminal to stop the server.
Your sentiment analyzer now has a proper web interface. In the next step, you'll deploy it to Hugging Face Spaces so anyone on the internet can use it.
Deploy to Hugging Face Spaces
Your app works locally. Now it is time to put it on the internet so anyone with a link can use it.
Hugging Face Spaces is a free hosting platform for ML apps. You push your code to a Space repository using Git, and Spaces automatically builds and deploys your app at a public URL.
In this step, get ready to:
- Create a new Hugging Face Space with the Gradio SDK.
- Create a requirements.txt file and push your app to the Space using Git.
- Verify your app is live and publicly accessible.
Create a new Space on Hugging Face
A Space is a Git repository on Hugging Face that automatically builds and hosts your app. You create one through the web interface, then push code to it like any Git repo.
- Open your browser and go to huggingface.co/new-space.
- Enter a name for your Space in the Space name field. Use something like sentiment-analyzer.
- Under Select the Space SDK, select Gradio.
- Leave the visibility set to Public.
- Click Create Space.
You will be redirected to your new Space page. It shows instructions for cloning the repository.
What is a Space?
A Hugging Face Space stores your code in a Git repository. Each time you push a commit, the platform automatically rebuilds and restarts your app.
The Gradio SDK tells Spaces to pre-install Gradio for you, so you only need to list your other dependencies in requirements.txt.
Create requirements.txt and push your app to the Space
Your Space needs a requirements.txt file so the platform knows which Python packages to install when building your app.
- Create a new file called requirements.txt in your project folder by running this command in your terminal:
echo "transformers==5.10.2
torch" > requirements.txt
Why no Gradio in requirements.txt?
The Spaces runtime pre-installs Gradio for you when you select the Gradio SDK. You only need to list packages that Spaces does not already provide, like transformers and torch.
- Confirm the file was created by running:
cat requirements.txt
You should see two lines: transformers==5.10.2 and torch.
Now clone your Space repository and push your files to it.
- Clone your Space repository by running this command (replace the username and space name with your own):
git clone https://huggingface.co/spaces/[[HF_USERNAME="your-username"]]/[[SPACE_NAME="your-space-name"]]
Where do I find my clone URL?
On your Space page, click the dropdown menu in the top right corner and select Clone repository. You will see the exact HTTPS URL to copy.
- Move into the cloned Space folder by running:
cd [[SPACE_NAME="your-space-name"]]
- Copy your app.py and requirements.txt into the Space folder by running:
cp ../app.py .
cp ../requirements.txt .
Adjust the path if needed
If your project files are in a different location, adjust the ../ path to point to where app.py and requirements.txt live on your machine.
- Stage, commit, and push your files by running these commands:
git add .
git commit -m "Add sentiment analysis app"
git push
What does this do?
These three commands add your files to Git's staging area, save them as a commit, and upload them to your Space on Hugging Face. Once the push completes, Spaces automatically starts building your app.
You should see Git upload your files successfully. If prompted for credentials, enter your Hugging Face username and your access token as the password.
Push rejected or authentication error?
Make sure you are using your Hugging Face access token (not your account password) when prompted for credentials. You created this token when you ran huggingface-cli login in Step 1.
If you see a "repository not found" error, double-check that the clone URL matches your username and Space name exactly.
Why is my git push to Hugging Face Spaces failing?
Verify your app is live on the Space
After pushing, Spaces builds your app automatically. This takes a couple of minutes the first time because it needs to install PyTorch and Transformers.
- Go to your Space URL in your browser: https://huggingface.co/spaces/ followed by your username and Space name.
- Wait for the status indicator at the top to show Running. The build can take 2-5 minutes on the first deploy.
- Once it is running, type a sentence into the text box and click Submit.
- Confirm you see a sentiment result (POSITIVE or NEGATIVE with a confidence score).
What should I see?
Your Space page displays your Gradio app with the title, description, and example inputs you defined in app.py. Anyone with the URL can use your app. No login required for visitors.
🙋♀️ Space stuck on Building or showing an error?
Click the Logs tab on your Space page to see the build output. Look for any package installation errors.
Make sure your requirements.txt contains exactly transformers==5.10.2 and torch on separate lines. A typo in the package name will cause the build to fail.
Help me debug why my Hugging Face Space is not building correctly.
✔️ Awesome, I've got everything!
Great. Double check you have saved requirements.txt and confirmed your Space is running.
ⓧ I'd like to double check the full code
Here is the complete requirements.txt file:
transformers==5.10.2
torch
And here is the complete app.py that should be in your Space:
import gradio as gr
from transformers import pipeline
# Load the sentiment analysis pipeline
classifier = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",
)
def analyze_sentiment(text):
"""Analyze the sentiment of input text."""
if not text.strip():
return "Please enter some text to analyze."
result = classifier(text)[0]
label = result["label"]
score = result["score"]
emoji = "\U0001f60a" if label == "POSITIVE" else "\U0001f61e"
return f"{emoji} {label} (confidence: {score:.4f})"
demo = gr.Interface(
fn=analyze_sentiment,
inputs=gr.Textbox(
label="Enter text to analyze",
placeholder="Type a sentence here...",
lines=3,
),
outputs=gr.Textbox(label="Sentiment Result"),
title="\U0001f917 Sentiment Analyzer",
description="Analyze the sentiment of any text using DistilBERT, a lightweight transformer model fine-tuned on SST-2. Part of a Hugging Face ecosystem tour!",
examples=[
["I love this product, it works amazingly well!"],
["This is the worst experience I've ever had."],
["The weather today is okay, nothing special."],
],
)
if __name__ == "__main__":
demo.launch()
Your sentiment analysis app is now live on the internet. You have a public URL that anyone can visit to analyze text with your model. Next up, tackle the Secret Mission to extend your app with multiple NLP tasks.
Secret mission
Multi-Task Analysis App
Your sentiment analyzer is live, but what if users could do more than just detect sentiment? In this secret mission, you'll extend your app with summarization and zero-shot classification, giving users a tabbed interface to analyze text with multiple models in one place.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely locally and on the free Hugging Face Spaces tier, so there are no ongoing costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- Local project files: explore_pipeline.py, explore_datasets.py, inference_api.py, app.py, and requirements.txt.
- Hugging Face Space (deployed Gradio app).
- Hugging Face CLI authentication token stored locally.
- Python packages: transformers, huggingface_hub, datasets, gradio, and torch.
Keep everything running
No action needed. Choose this if you are still actively building or want to revisit the project later.
- Your Hugging Face Space stays live on the free tier. It automatically sleeps after a period of inactivity and wakes up when someone visits it.
- Your local project files remain on your Desktop.
- Your Hugging Face CLI token remains stored locally for future use.
- Installed Python packages remain available in your environment.
Pause - I'll come back to this later
Shut down running processes to free up memory while keeping your files and Space intact.
- Pause your Hugging Face Space by opening it in the browser, clicking Settings, and selecting Pause Space. A paused Space stops executing until you manually restart it.
- Your local project files stay on your Desktop for when you are ready to continue.
Delete - I don't want to use this again
Remove all project resources and start fresh.
- Delete your Hugging Face Space by opening it in the browser, clicking Settings, scrolling to the bottom, and clicking Delete this space. Confirm by clicking I understand, delete this space.
- Remove your locally stored Hugging Face token by running:
hf auth logout
- Delete your local project folder from your Desktop. On macOS or Linux:
cd ~/Desktop
rm -rf [[PROJECT_FOLDER="your-project-folder-name"]]
On Windows:
cd ~\Desktop
rmdir /s /q [[PROJECT_FOLDER="your-project-folder-name"]]
- Uninstall the Python packages by running:
pip uninstall transformers huggingface_hub datasets gradio torch -y
Nice Work!
Nice Work!
You just toured the entire Hugging Face ecosystem and deployed a live AI-powered web app. From browsing models on the Hub to serving predictions to anyone with a URL, you now have hands-on experience with the tools ML engineers use every day.
Here's what you accomplished:
- Ran a pre-trained DistilBERT model locally using the Transformers pipeline for sentiment analysis.
- Called models remotely via the Inference Providers API using InferenceClient without downloading any model weights.
- Built a polished Gradio web interface and deployed it live to Hugging Face Spaces with a shareable public URL.
- Extended your app with multi-task analysis combining sentiment, summarization, and zero-shot classification into a tabbed interface.
Ready to quiz yourself?