-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable selection of GPU on inference page #1511
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
from digits.status import Status | ||
from digits.utils import filesystem as fs | ||
from digits.utils import constants | ||
from digits.utils.forms import fill_form_if_cloned, save_form_to_job | ||
from digits.utils.forms import fill_form_if_cloned, save_form_to_job, get_selected_gpu | ||
from digits.utils.routing import request_wants_json, job_from_request | ||
from digits.webapp import scheduler | ||
|
||
|
@@ -309,8 +309,10 @@ def show(job, related_jobs=None): | |
template, context = extension.get_inference_template(form) | ||
inference_form_html = flask.render_template_string(template, **context) | ||
|
||
generic_form = GenericImageModelForm() | ||
return flask.render_template( | ||
'models/images/generic/show.html', | ||
form=generic_form, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am a bit uneasy about passing the form here when all you need is the list of GPUs. Wouldn't it more explicit and self-explanatory to pass the list instead? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. Do you think this way is okay? |
||
job=job, | ||
view_extensions=view_extensions, | ||
related_jobs=related_jobs, | ||
|
@@ -361,6 +363,8 @@ def infer_one(): | |
else: | ||
resize = True | ||
|
||
selected_gpu = get_selected_gpu(flask.request.form) | ||
|
||
# create inference job | ||
inference_job = ImageInferenceJob( | ||
username=utils.auth.get_username(), | ||
|
@@ -370,6 +374,7 @@ def infer_one(): | |
epoch=epoch, | ||
layers=layers, | ||
resize=resize, | ||
gpu=selected_gpu | ||
) | ||
|
||
# schedule tasks | ||
|
@@ -446,6 +451,8 @@ def infer_extension(): | |
if 'show_visualizations' in flask.request.form and flask.request.form['show_visualizations']: | ||
layers = 'all' | ||
|
||
selected_gpu = get_selected_gpu(flask.request.form) | ||
|
||
# create inference job | ||
inference_job = ImageInferenceJob( | ||
username=utils.auth.get_username(), | ||
|
@@ -455,6 +462,7 @@ def infer_extension(): | |
epoch=epoch, | ||
layers=layers, | ||
resize=False, | ||
gpu=selected_gpu | ||
) | ||
|
||
# schedule tasks | ||
|
@@ -539,6 +547,8 @@ def infer_db(): | |
else: | ||
resize = True | ||
|
||
selected_gpu = get_selected_gpu(flask.request.form) | ||
|
||
# create inference job | ||
inference_job = ImageInferenceJob( | ||
username=utils.auth.get_username(), | ||
|
@@ -548,6 +558,7 @@ def infer_db(): | |
epoch=epoch, | ||
layers='none', | ||
resize=resize, | ||
gpu=selected_gpu | ||
) | ||
|
||
# schedule tasks | ||
|
@@ -633,6 +644,8 @@ def infer_many(): | |
else: | ||
resize = True | ||
|
||
selected_gpu = get_selected_gpu(flask.request.form) | ||
|
||
paths = [] | ||
|
||
for line in image_list.readlines(): | ||
|
@@ -664,6 +677,7 @@ def infer_many(): | |
epoch=epoch, | ||
layers='none', | ||
resize=resize, | ||
gpu=selected_gpu | ||
) | ||
|
||
# schedule tasks | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,14 @@ | |
|
||
{% extends "job.html" %} | ||
{% from "helper.html" import serve_file %} | ||
{% from "helper.html" import mark_errors %} | ||
|
||
{% block job_content %} | ||
|
||
<script src="{{ url_for('static', filename='js/model-graphs.js', ver=dir_hash) }}"></script> | ||
|
||
{% set task = job.train_task() %} | ||
{% set show_multi_gpu_form = form.select_one_of_gpus.choices| length > 2 %} | ||
|
||
<div class="row"> | ||
<div class="col-sm-6"> | ||
|
@@ -102,13 +104,9 @@ <h4 class='text-center'>Dataset</h4> | |
{% endif %} | ||
> | ||
<h2>Trained Models</h2> | ||
<div class="row"> | ||
<div class="col-sm-12"> | ||
<label for="snapshot_epoch">Select Model</label> | ||
</div> | ||
</div> | ||
<div class="row"> | ||
<div class="col-sm-6"> | ||
<label for="snapshot_epoch">Select Model</label> | ||
<div class="form-group"> | ||
<select id="snapshot_epoch" name="snapshot_epoch" class="form-control"> | ||
</select> | ||
|
@@ -139,9 +137,36 @@ <h2>Trained Models</h2> | |
updateSnapshotList({% autoescape false %}{{task.snapshot_list()}}{% endautoescape %}); | ||
</script> | ||
</div> | ||
{% if show_multi_gpu_form %} | ||
<button | ||
formaction="{{url_for('digits.model.views.download', job_id=job.id())}}" | ||
formmethod="post" | ||
formenctype="multipart/form-data" | ||
class="btn btn-info"> | ||
Download Model | ||
</button> | ||
<button | ||
formaction="{{url_for('digits.model.views.to_pretrained', job_id=job.id())}}" | ||
formmethod="post" | ||
formenctype="multipart/form-data" | ||
class="btn btn-success"> | ||
Make Pretrained Model | ||
</button> | ||
{% endif %} | ||
</div> | ||
{% if show_multi_gpu_form %} | ||
<div class="col-sm-6"> | ||
<div class="form-group{{mark_errors([form.select_one_of_gpus])}}"> | ||
{{form.select_one_of_gpus.label}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's indeed better to use the WTForm fields here but it's inconsistent with the rest of the file... so I'm not sure about that... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've changed that too. What you think? |
||
{{form.select_one_of_gpus(class='form-control', size=4)}} | ||
</div> | ||
</div> | ||
{% else %} | ||
<div class="col-sm-6"> | ||
<button | ||
<label for="empty space"> </label> | ||
</div> | ||
<div class="col-sm-6"> | ||
<button | ||
formaction="{{url_for('digits.model.views.download', job_id=job.id())}}" | ||
formmethod="post" | ||
formenctype="multipart/form-data" | ||
|
@@ -156,6 +181,7 @@ <h2>Trained Models</h2> | |
Make Pretrained Model | ||
</button> | ||
</div> | ||
{% endif %} | ||
</div> | ||
{% if task.get_framework_id() in framework_ids %} | ||
<div class="row"> | ||
|
@@ -184,6 +210,7 @@ <h3>Test a single image</h3> | |
</div> | ||
</div> | ||
</div> | ||
|
||
<script type="text/javascript"> | ||
// When you fill in one field, the other gets blanked out | ||
$("#image_path").change(function() { $("#image_file").val(""); }); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens here if there are no GPUs on the system?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lukeyeager the same behavior that you'd get if you were to start a training job without a GPU:
CUDA_VISIBLE_DEVICES
), then you'd get the page without multi-gpu form and your job will fail exactly as the train job fails currently:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable to me!