Lesson 2 official topic

Hi all,

I’ve been following the lectures and coding along, but due to library updates and differences between local model inference and deployment on Hugging Face, I ran into a few issues.

For those folks who look for quick fixes and to the point:

1. Set Python Version
After cloning the Hugging Face Space to your local machine, edit the README.md and add this line at the end:

python_version: '3.12'

This sets the Python version for your Space. If you are curious about the space configuration, here is the link.

2. Update requirements.txt
Use the following dependencies:

gradio==3.50.0
fastai==2.8.3

3. Adjust Gradio API Usage
Gradio’s API has changed slightly since Jeremy recorded the video. Update these two lines in app.py:

image = gr.Image()
label = gr.Label()

Push your changes and enjoy a smooth deployment!

For the Curious Minds – Recreating Jeremy’s Original Setup:

If you want to replicate the environment, probably the one that Jeremy used during the lecture, here’s what you need:

requirements.txt:

gradio==5.42.0
fastai==2.7.19
cloudpickle==3.1.1

In app.py:

image = gr.Image()
label = gr.Label()

Important:
If your model was exported using a newer version of fastai, it won’t work with 2.7.19 due to architectural changes. You’ll need to retrain and export your model using fastai==2.7.19. For local training, also include:

fastbook==0.0.26

Why These Changes Were Necessary:

I faced several deployment issues when following the lecture:

  • My local setup used Python 3.12, but Hugging Face Spaces defaulted to 3.10.
  • Fastai’s internal architecture changed between versions, causing incompatibility.
  • cloudpickle needed to be updated for proper serialization.
  • Gradio’s API moved Image and Label components out of the inputs and outputs modules, and they no longer accept the shape argument.

To avoid long deployment cycles and error debugging on Hugging Face, I set everything up locally using a Python 3.10 virtual environment, resolved the issues, and then pushed the working version.

Hope this helps anyone starting the lectures in 2025!

4 Likes

Here is an updated example of some of the topics from lessons 1 & 2. Inference is done on windows PC rather than gradio etc..

1 Like

Does anyone know a good image api? I tried used DDGS image search but it only works once. After the initial successful search any subsequent one returns:

DDGSException: No results found

I’ve changed the environments: Kaggle and Paperspace
I’ve tried setting a delay in case of rate limiting

This is driving me crazy because everyone seems to be able to use DDGS but it doesn’t work when I run it. I’ve even tried “Copy & Edit” with people’s notebooks and I get the same result.

I got around it by doing:

results = DDGS().images(
    query="Grizzly Bear",
    region="us-en",
    safesearch="moderate",
    color="color",
    max_results=10,
)
1 Like

I’m not having any issues using the ddgs api:

from ddgs import DDGS # DuckDuckGo has changed the api so we need to update (again)
from fastcore.all import *
from fastdownload import download_url
from fastai.vision.all import *

def search_images(keywords, max_images=200): return L(DDGS().images(keywords, max_results=max_images)).itemgot('image')

urls = search_images('bird photos', max_images=10)
print(urls[0])

dest = 'bird.jpg'
download_url(urls[0], dest, show_progress=False)

im = Image.open(dest)
im.to_thumb(256,256)

This code works just fine on my macbook laptop.

Interesting. Are you also using Kaggle or completely your macbook?

With your code snippet I get the same outcome: 1st run works, any after DDGSException: No results found

The ‘fix’ I found still works for me at least.

This is the complete error I get if anyone else can help. I’ve tried both Paperspace and Kaggle. Internet is enabled for both and I verified it as well. Turning off internet yields the same error message, but the cell runs for a few seconds longer.

---------------------------------------------------------------------------
DDGSException                             Traceback (most recent call last)
/tmp/ipykernel_36/605048266.py in <cell line: 0>()
----> 1 urls = search_images('dog photos', max_images=10)
      2 print(urls[0])
      3 
      4 dest = 'bird.jpg'
      5 download_url(urls[0], dest, show_progress=False)

/tmp/ipykernel_36/1439059728.py in search_images(keywords, max_images)
      4 from fastai.vision.all import *
      5 
----> 6 def search_images(keywords, max_images=200): return L(DDGS().images(keywords, max_results=max_images)).itemgot('image')
      7 
      8 urls = search_images('bird photos', max_images=10)

/usr/local/lib/python3.11/dist-packages/ddgs/ddgs.py in images(self, query, **kwargs)
    222     def images(self, query: str, **kwargs: Any) -> list[dict[str, Any]]:
    223         """Perform an image search."""
--> 224         return self._search("images", query, **kwargs)
    225 
    226     def news(self, query: str, **kwargs: Any) -> list[dict[str, Any]]:

/usr/local/lib/python3.11/dist-packages/ddgs/ddgs.py in _search(self, category, query, keywords, region, safesearch, timelimit, max_results, page, backend, **kwargs)
    214         if "timed out" in f"{err}":
    215             raise TimeoutException(err)
--> 216         raise DDGSException(err or "No results found.")
    217 
    218     def text(self, query: str, **kwargs: Any) -> list[dict[str, Any]]:

DDGSException: No results found.

Upon further testing it seems like the argument I need is color

# This works for me 
results = DDGS().images(
    query="Grizzly Bear",
    color="color"
)
# This does not
results = DDGS().images(
    query="Grizzly Bear",
    color="color"
)

So if anyone else runs into this issue you can use

def search_images(keywords, max_images=10, color=color'):
    results = DDGS().images(
        query=keywords,
        max_results=max_images,
        color=color,
    )
    return L(results).itemgot('image')

I’ve also verified by running other notebooks linked here that didn’t work for me before and I updated the definition of search_images to include color.

same here

Used for car classification weather it is crashed or perfectly fine. For now it only works for red cars. Error is showing DDGSException: No results found. So i needed to use color to solve the problem. and so i have used red color.

color = "color"
Should query for results in (any) color

1 Like

Thanks it worked.

I realize my code block for this works for me and this doesn’t was wrong. It should be

# This works for me 
results = DDGS().images(
    query="Grizzly Bear",
    color="color"
)
# This does not
results = DDGS().images(
    query="Grizzly Bear"
)

this just saved my butt. I have been struggling with this cell for 4 days. THIS!!!

1 Like

Hello,

I’ve been facing issues with hosting my model to HuggingFace for about a week now. Can someone please help me with this?

app.py (worked perfectly fine with gradio, btw)

import gradio as gr
from fastai.vision.all import *
from pathlib import Path
import numpy as np

model_path = Path("screws_model.pkl")
learn = load_learner(model_path)
categories = ('m4', 'm5')

def classify_img(img):
  pred, idx, probs = learn.predict(img)
  return dict(zip(categories, map(float, probs)))

image = gr.Image(height=192, width=192)
label = gr.Label()
examples = ['m4_1.jpg', 'm4_5.jpg', 'screw_test.jpg']

intf = gr.Interface(fn=classify_img, inputs=image, outputs=label, examples=examples)
intf.launch(inline=False, share=True)

requirements.txt

fastai
torch
torchvision
gradio
numpy
Pillow

Exported Model

!pip install -Uqq fastai
from fastai.vision.all import *
from PIL import Image
from IPython.display import Image as DisplayImage

path = Path('/content/Screws/')

dls = DataBlock(
    blocks=(ImageBlock, CategoryBlock),
    get_items=get_image_files,
    splitter=RandomSplitter(valid_pct=0.2, seed=42),
    get_y=parent_label,
    item_tfms=[Resize(192, method='squish')]
).dataloaders(path)

aug_transforms = aug_transforms(mult=2.0)

learn = cnn_learner(dls, resnet18, metrics=error_rate)
learn.fine_tune(4) #4 epochs

learn.export("screws_model.pkl")

Error

File "/home/user/app/app.py", line 11, in classify_img
    pred, idx, probs = learn.predict(img)
...
TypeError: unsupported operand type(s) for +: 'int' and 'dict'

Tried adjusting the versions in requirements.txt, tried dealing with it as a GPU to CPU issue, and even tried converting the image to PIL before learn.predict(img), but to no avail.
From what I understand, the problem is either with inconsistency in HF’s versions and Colab’s (where I trained the model) or with the model itself (maybe some augmentations I used? squish?).

I used ChatGPT to create a cat dog to test the model:
https://jakeluckie-cat-dog2.hf.space/?__theme=system&deep_link=oG_pSvw5kTk

Thought it might be funny/interesting to someone

Hi everyone, I’ve just completed part 1 lesson 2 and wanted to share my very first project: https://fugazzeta.pages.dev/

It’s a pizza classifier. Probably only works if you’re in Argentina as it to classify whether a pizza is a “fugazzeta” or not.

The model works best once images are cropped to show the pizza centered. So I guess I could run another model to classify an image between “pizza” and “not pizza” and then run the fugazzeta model on the pizza element.

Anyway, I probably should do lesson 3 before any of this, but it’s fun to test while learning.

Hi guys!
I couldn’t find the testing notebook whch was actually uploaded to HF Spaces.

Will be grateful if someone can share it!

Hi everyone!

For anyone else that’s struggling getting the images to train the model in the notebook, here’s what worked for me:

  • We’ll use a new package called icrawler, which you can install with pip (like the first cell of the notebook is installing fastbook)

  • We will ignore the search cell

results = search_images_bing(key, 'grizzly bear')
ims = results.attrgot('contentUrl') len(ims)
  • For the download cell, that initially looks like this:
if not path.exists():
    path.mkdir()
    for o in bear_types:
        dest = (path/o)
        dest.mkdir(exist_ok=True)
        results = search_images_bing(key, f'{o} bear')
        download_images(dest, urls=results.attrgot('contentUrl'))
  • We can replace with:
if not path.exists():
    path.mkdir()

from icrawler.builtin import GoogleImageCrawler

for o in bear_types:
    dest = (path/o)
    dest.mkdir(exist_ok=True)
    
    # Download images directly
    crawler = GoogleImageCrawler(storage={'root_dir': str(dest)})
    crawler.crawl(keyword=f'{o} bear', max_num=150, min_size=(200, 200))
    
    print(f"Downloaded images for {o} bear")

And that’s it. Hope it helps!

Hi Fastai community,

In lesson 2, in the section about clean, it needs a AZURE_SEARCH_KEY.

Bing Search APIs retired on August 11, 2025.

What would be the suggested alternative? So I can get the examples working for the lesson.

Found solution in this post. Lesson 2 official topic - #879 by DmitryR

You’re a lifesaver. I’ve been wading through error after error, feeling like I was playing whackamole extremely unsuccessfully. Adding in the explicit versions in the requirements.txt made them all disappear!

Thanks so much for adding this in for those of us (very) late to the party.

1 Like

hi, did you find the solution to the problem?

Hey, sorry, nope. I gave up on it back then. It’s mostly a version issue. Have you tried using Claude with this?