-
Notifications
You must be signed in to change notification settings - Fork 7
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
Feature/inference api #117
Conversation
can you fix mypy checks? |
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.
this PR is incomplete. users are expected to use the Studio
class to interact w/ the API, not the API methods directly. methods need to be added to that class that call the API methods (like all of the other functionalities do)
… of text input files with actual text data columns used for prediction
a469401
to
9ab9d28
Compare
cleanlab_studio/internal/api/api.py
Outdated
if modality == "text": | ||
header_io = io.StringIO(header) | ||
input_batch = io.StringIO("\n".join(chain(header_io, batch))) |
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.
see comment in backend
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.
Got it. I'll change the lambda function to take care of this. Didn't want to touch lambda as much as possible since it's not in a state that's easy to fix and deploy right now.
cleanlab_studio/internal/api/api.py
Outdated
def download_prediction_results(result_url: str) -> io.StringIO: | ||
"""Downloads prediction results from presigned URL.""" | ||
res = requests.get(result_url) | ||
return io.StringIO(res.text) |
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.
no need to do this buffering, just pass res.raw
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.
I think we do need this buffering since we want to return a numpy array for the results to the user.
cleanlab_studio/studio/inference.py
Outdated
# Set timeout to 10 minutes as inference won't take longer than 10 minutes typically and | ||
# to prevent users from getting stuck in this loop indefinitely when there is a failure |
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.
failures should be reported in the status, correct?
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.
Yeah that would be ideal, but there has been cases where the status updates did not happen properly for lambda failures in the past and queries were stuck in the running
status even after they have failed. Just wanted to make sure this case doesn't confuse users.
cleanlab_studio/studio/inference.py
Outdated
status = resp["status"] | ||
|
||
if status == "error": | ||
return resp["error_msg"] |
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.
we need to raise an error here. returning an error message is not a sensible API for users
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.
Changed to raising an APIError
cleanlab_studio/studio/inference.py
Outdated
results_converted: Predictions = pd.read_csv(results).to_numpy() | ||
return results_converted | ||
|
||
@functools.singledispatchmethod |
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.
should remove (relic from my dev work)
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.
removed
cleanlab_studio/studio/inference.py
Outdated
status: Optional[str] = resp["status"] | ||
# Set timeout to 10 minutes as inference won't take longer than 10 minutes typically and | ||
# to prevent users from getting stuck in this loop indefinitely when there is a failure | ||
timeout = time.time() + 60 * 10 |
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.
timeout should be user configurable
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.
I'll add timeout as an optional parameter users can add when calling predict.
cleanlab_studio/internal/api/api.py
Outdated
def download_prediction_results(result_url: str) -> io.StringIO: | ||
"""Downloads prediction results from presigned URL.""" | ||
res = requests.get(result_url) | ||
return io.StringIO(res.text) |
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.
It is unnecessary and wasteful to rebuffer the entire result here. Just use res.raw
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.
Removed this function entirely and used url directly in pandas to read results
Failing in dev currently:
|
Can you let me know which model and test input you tested with? |
Looked at the input file here and it seems like there is a formatting error in the header. |
cleanlab_studio/studio/inference.py
Outdated
resp = api.get_prediction_status(self._api_key, query_id) | ||
status: Optional[str] = resp["status"] | ||
# Set timeout to prevent users from getting stuck indefinitely when there is a failure | ||
timeout_limit = time.time() + timeout | ||
|
||
while status == "running" and time.time() < timeout_limit: | ||
resp = api.get_prediction_status(self._api_key, query_id) | ||
status = resp["status"] | ||
# Set time.sleep so that the while loop doesn't flood backend with api calls | ||
time.sleep(3) |
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.
make timeout configurable and cleanup logic
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.
lgtm! just a couple nits
From one of our client calls, we found a demand to use model deployment in automatic data pipelines using the studio python api client. In this PR, we built the api client side code for model deployment.
To test, you need to need to pull the branch in this PR from the backend code.