Deployment Platform: Render ✅

Hi Ajaykumaar are you using this link https://course.fast.ai/deployment_render.html as all the instructions are there, it is quite clear.

I have now used this exact document to build 5 image classifiers.

If you read the above document it tells you in this link ( Google Drive: Use this link generator what to do once you have uploaded the export.pkl to your google drive.

Hope this helps.

mrfabulous1. :smiley::smiley:

1 Like

Hi Derek,

Many thanks, It worked.

Hi thanks, I’ve created the link using link generator. How do i do the " customize your app" part ?
Where will server.py file be ?
@mrfabulous1

Hey!
So, I was able to delpoy my DL model on Render. It works fine on Desktop, but it get stuck on ‘Analyzing’ when I try it on mobile. Any ideas how to fix this? @anurag

Here’s the link to the live site - https://gym-trainer.onrender.com/

1 Like

No problem!

HI, I was able to deploy the image classifier model on render. But, when i upload an image, it is stuck on analyzing. On seeing the event log i see some asgi erroor and conv2d attribute error. Any help on how I can fix this? I was able to get the prediction just in my notebook though

ul 8 09:29:18 AM INFO: (‘10.104.13.98’, 52720) - “GET / HTTP/1.1” 200
Jul 8 09:29:19 AM INFO: (‘10.104.13.98’, 52720) - “GET /static/style.css HTTP/1.1” 304
Jul 8 09:29:19 AM INFO: (‘10.104.13.98’, 52728) - “GET /static/client.js HTTP/1.1” 304
Jul 8 09:29:42 AM INFO: (‘10.104.13.98’, 53008) - “POST /analyze HTTP/1.1” 500
Jul 8 09:29:42 AM ERROR: Exception in ASGI application
Jul 8 09:29:42 AM Traceback (most recent call last):
File “/usr/local/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py”, line 368, in run_asgi
result = await app(self.scope, self.receive, self.send)
File “/usr/local/lib/python3.7/site-packages/starlette/applications.py”, line 133, in call
await self.error_middleware(scope, receive, send)
File “/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py”, line 122, in call
raise exc from None
File “/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py”, line 100, in call
await self.app(scope, receive, _send)
File “/usr/local/lib/python3.7/site-packages/starlette/middleware/cors.py”, line 84, in call
await self.simple_response(scope, receive, send, request_headers=headers)
File “/usr/local/lib/python3.7/site-packages/starlette/middleware/cors.py”, line 140, in simple_response
await self.app(scope, receive, send)
File “/usr/local/lib/python3.7/site-packages/starlette/exceptions.py”, line 73, in call
raise exc from None
File “/usr/local/lib/python3.7/site-packages/starlette/exceptions.py”, line 62, in call
await self.app(scope, receive, sender)
File “/usr/local/lib/python3.7/site-packages/starlette/routing.py”, line 585, in call
await route(scope, receive, send)
File “/usr/local/lib/python3.7/site-packages/starlette/routing.py”, line 207, in call
await self.app(scope, receive, send)
File “/usr/local/lib/python3.7/site-packages/starlette/routing.py”, line 40, in app
response = await func(request)
File “app/server.py”, line 258, in analyze
prediction = learn.predict(img)[0]
File “/usr/local/lib/python3.7/site-packages/fastai/basic_train.py”, line 365, in predict
res = self.pred_batch(batch=batch)
File “/usr/local/lib/python3.7/site-packages/fastai/basic_train.py”, line 345, in pred_batch
preds = loss_batch(self.model.eval(), xb, yb, cb_handler=cb_handler)
File “/usr/local/lib/python3.7/site-packages/fastai/basic_train.py”, line 26, in loss_batch
out = model(*xb)
File “/usr/local/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 493, in call
result = self.forward(*input, **kwargs)
File “/usr/local/lib/python3.7/site-packages/torch/nn/modules/container.py”, line 92, in forward
input = module(input)
File “/usr/local/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 493, in call
result = self.forward(*input, **kwargs)
File “/usr/local/lib/python3.7/site-packages/torch/nn/modules/container.py”, line 92, in forward
input = module(input)
File “/usr/local/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 493, in call
result = self.forward(*input, **kwargs)
File “/usr/local/lib/python3.7/site-packages/torch/nn/modules/conv.py”, line 331, in forward
if self.padding_mode == ‘circular’:
File “/usr/local/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 539, in getattr
type(self).name, name))
AttributeError: ‘Conv2d’ object has no attribute 'padding_mode’

Hi Ajaykumaar
The server.py is in the directory below

app/server.py

If you look at the link from my previous post https://course.fast.ai/deployment_render.html go to the section

Customize the app for your model

  1. Edit the file server.py inside the app directory and update the model_file_url variable with the URL copied above.
  2. In the same file, update the line classes = ['black', 'grizzly', 'teddys'] with the classes from your model.

In section 1 put your generated url.
In section 2 put put your class names.

hope this helps

mrfabulous1 :smiley::smiley:

Tried the same requirements.txt and render worked. It was giving cuda 9.0 error with default requirements.txt. Thanks buddy!

Hi Abhijith
I tested your app.


It works fine on my Samsung Galaxy using Chrome and the Samsung Browser.
Though all the images I put in return undefined.

Have you you tried using smaller images and a different browser on your phone.

mrfabulous1 :grinning::grinning:

Hey!
Can you please try now? There was a bug earlier cause of which it was returning undefined. Thanks for the help!

Hi ab123
This works fine now on my Samsung phone using chrome and the Samsung browser.

mrfabulous1

Thank You @mrfabulous1
Any idea why its not working on other mobiles? I too use Chrome but on my mobile it is stuck. Wonder why? :thinking:

Good afternoon ab123

Can you do the following

  1. have you got any other browser on your mobile you can try.
  2. Can you install any other browser on your phone and try it.
  3. What version of chrome are you using on your mobile.
  4. Test your browser on another render app like the bears app on render.
  5. Test your app with one of the images from your test set and make sure it small like 20k.
  6. I am using Samsung Internet version 9.2.10.5 and the latest version of chrome.
  7. some people have had problems with various browsers. Safari on my desktop gets stuck in Analyzing.
  8. If you test all the above it should get you closer to solving the problem.

Cheers mrfabulous1 :grinning::smiley:

Hey!
Thanks for the info! I changed to Firefox and it worked! Also, it did work on a different version of Chrome, but do not know the exact release. Anyways, Thanks! @mrfabulous1

Hi ab123 Congratulations glad its working.

mrfabulous1 :smiley::smiley:

Hey guys! I’m currently prepping a deployment workshop/teaching for my Fast.AI study group at my University, and I’m revisiting the Render methodology as a baseline to utilize Starlette. While looking over the source code, I’m noticing that classes is never utilized in ‘serve.py’. Is it being used elsewhere? Or never utilized at all? Thanks!

One other question, if we want to upload and analyze a CSV document, how do I set it up so it’s readable? For example, my customer sends a CSV full of URLs and I want to download them all, so my analyze function looks like so:

@app.route('/analyze', methods=['POST'])
async def analyze(request):
    data = await request.form()
    content = data['content']
    mkdir('Downloaded_Images')
    download_images(content, 'Downloaded_Images')
    path2 = Path('Downloaded_Images')
    data = ImageList.from_folder(path)
    learn = load_learner(path, export_file_name, test=data)
    y, _ = learn.get_preds(DatasetType.Test)
    y = torch.argmax(y, dim=1)
    preds = [learn.data.classes[int(x)] for x in y]
    resultsFile = open('results.csv', 'wb')
    wr = csv.writer(resultsFile)
    wr.writerows([preds])
    return FileResponse('results.csv')

I know that currently it does not work, as I get a ‘KeyError: ‘content’’ but I am unsure where to go from here. Any advice? Thanks :slight_smile:

I’d log the contents of your XMLHttprequest to the console in the browser to check what’s being sent to the server and perhaps use the debugger on the server side to inspect what ‘data’ looks like also

1 Like

@OllieG, thank you for the reply :slight_smile: I’m very new to web-development so I’m a little bit lost there. I tried looking at the console and it says there was an error in the client.js (something I didn’t think to change)

var el = x => document.getElementById(x);

function showPicker() {
  el("file-input").click();
}

function showPicked(input) {
  el("upload-label").innerHTML = input.files[0].name;
  var reader = new FileReader();
  reader.onload = function(e) {
    el("image-picked").src = e.target.result;
    el("image-picked").className = "";
  };
  reader.readAsDataURL(input.files[0]);
}

function analyze() {
  var uploadFiles = el("file-input").files;
  if (uploadFiles.length !== 1) alert("Please select a file to analyze!");

  el("analyze-button").innerHTML = "Analyzing...";
  var xhr = new XMLHttpRequest();
  var loc = window.location;
  xhr.open("POST", `${loc.protocol}//${loc.hostname}:${loc.port}/analyze`,
    true);
  xhr.onerror = function() {
    alert(xhr.responseText);
  };
  xhr.onload = function(e) {
    if (this.readyState === 4) {
      var response = JSON.parse(e.target.responseText);
      el("result-label").innerHTML = `Result = ${response["result"]}`;
    }
    el("analyze-button").innerHTML = "Analyze";
  };

  var fileData = new FormData();
  fileData.append("file", uploadFiles[0]);
  xhr.send(fileData);
}

I think I need to adjust how fileData is being made? Or what do I need to adjust from here? Thanks :slight_smile:

Edit: I changed fileData to accept a CSS,

fileData = new CommaSeparatedStrings()

but I’m unsure where to go from here.

Edit x2: Got it working! For anyone wanting to read csv documents to do whatever (my long-term goal was to read a csv of customer data for a tabular model) you need to do the fileData declaration, and in the analyze function (or prepData if you want) do the following:

data = await request.form()
content = await (data['file'].read())
s = str(content, 'utf-8')
data = StringIO(s)
content = pd.read_csv(data)

Hope this can help others :slight_smile:

2 Likes

Thank You @mrfabulous1