-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
Suppressing Stan optimizer printing in Python #223
Comments
I worked on this a bit for #170 and didn't make it very far. Help here is greatly appreciated :-) We may need an upstream change. |
Here's a decorator that DOES suppress output: # from https://stackoverflow.com/questions/11130156/suppress-stdout-stderr-print-from-python-functions
class suppress_stdout_stderr(object):
'''
A context manager for doing a "deep suppression" of stdout and stderr in
Python, i.e. will suppress all print, even if the print originates in a
compiled C/Fortran sub-function.
This will not suppress raised exceptions, since exceptions are printed
to stderr just before a script exits, and after the context manager has
exited (at least, I think that is why it lets exceptions through).
'''
def __init__(self):
# Open a pair of null files
self.null_fds = [os.open(os.devnull, os.O_RDWR) for x in range(2)]
# Save the actual stdout (1) and stderr (2) file descriptors.
self.save_fds = (os.dup(1), os.dup(2))
def __enter__(self):
# Assign the null pointers to stdout and stderr.
os.dup2(self.null_fds[0], 1)
os.dup2(self.null_fds[1], 2)
def __exit__(self, *_):
# Re-assign the real stdout/stderr back to (1) and (2)
os.dup2(self.save_fds[0], 1)
os.dup2(self.save_fds[1], 2)
# Close the null files
os.close(self.null_fds[0])
os.close(self.null_fds[1])
# used like
with suppress_stdout_stderr():
p = Propet(*kwargs).fit(training_data) |
@randlet Awesome. Has this been pulled? |
Not yet, but I would be happy to work up a PR this week if @bletham is ok with using a context manager to (optionally) suppress output. |
Actually, I don't know how the copyright/FB contributors agreement would work for this. I didn't write the code and AFAIK Stack Overflow snippets (prior to 2016) are licensed with CC Share Alike license. @bletham do you know if it's possible for you to accept PR's for code that has a CC-SA license? |
@randlet thanks for posting this, this is really great and should be immediately useful to people. I'm not sure about the license thing. I think I'm inclined to just leave this issue open so that people can find and use the decorator, and then wait a bit longer on the Stan team for an upstream fix. They're definitely aware of the issue (stan-dev/rstan#49) and say as of April that it will be suppressed soon, then it'll just be a matter of adding the verbose arg to prophet. |
That approach makes good sense to me. Thanks! |
Just wanted to post an update to this. We are running Prophet in a long running process doing lots of forecasting and found we were running out of file descriptors pretty quickly causing issues on the server. I finally traced it back to the decorator posted above which leaks 2 file descriptors every time it is used. I have modified it to the following with success: class suppress_stdout_stderr(object):
'''
A context manager for doing a "deep suppression" of stdout and stderr in
Python, i.e. will suppress all print, even if the print originates in a
compiled C/Fortran sub-function.
This will not suppress raised exceptions, since exceptions are printed
to stderr just before a script exits, and after the context manager has
exited (at least, I think that is why it lets exceptions through).
'''
def __init__(self):
# Open a pair of null files
self.null_fds = [os.open(os.devnull, os.O_RDWR) for x in range(2)]
# Save the actual stdout (1) and stderr (2) file descriptors.
self.save_fds = [os.dup(1), os.dup(2)]
def __enter__(self):
# Assign the null pointers to stdout and stderr.
os.dup2(self.null_fds[0], 1)
os.dup2(self.null_fds[1], 2)
def __exit__(self, *_):
# Re-assign the real stdout/stderr back to (1) and (2)
os.dup2(self.save_fds[0], 1)
os.dup2(self.save_fds[1], 2)
# Close the null files
for fd in self.null_fds + self.save_fds:
os.close(fd) |
Hi. I've got here from issue #219, yet this solution definitely does not work with Prophet.fit logger.INFO messages like "Disabling yearly seasonality..." and "Disabling daily seasonality...". I'm quite at a loss of how to get rid of them, actually. Nothing works. |
Nevermind. Turns out that if you specify "daily_seasonality=False" etc. the messages disappear. Although why on earth an unspecified parameter should generate a console output, Facebook knows. |
Those messages can be disabled by setting the logging level for fbprophet to something above INFO:
The reason for them is to avoid a scenario where a new user fits a time series with default values, seasonality is disabled e.g. due to too short a time series, but the user doesn't know this and is left wondering why the seasonality doesn't show up in the plot like in the documentation. With the info message they will know that it was on purpose and not a bug. |
Hello Ben, |
Any progress on this? I just started to experiment with Prophet in an existing application which spits out HTML to stdout. All this business about log joing probabilities and Hessians is wreaking havoc with that. I finally had to wrap this sort of business around my prophet calls:
I will eventually turn that into a decorator. Still would be nice to have an official way to do that suppression, one which didn't require so many system calls... (I'm guessing Stan has no clean way to tell it to shut up?) I'm using 0.2.1 (package from Conda forge). Maybe a later version has this problem solved? |
The upstream issue in Stan is still open, there is nothing in the later version of prophet to fix this. I was hoping for an upstream fix to avoid having to mess around with redirecting stderr, but we may have to just do it for the next version. In the meantime a decorator like that is the way to go. |
Is there a link to the docs on how to do this? I'm running thousands of simulations and this is killing me... |
Hi drcrook1, I'm not sure what did the job for me, but it was either logging or suppress_stdout_stderr above.
Hopes it helps. |
Errr.. There was a question by shaidams64 which I don't see now, but I would answer anyway: |
I found that : |
@eromoe hi, it fixes using this. This will help you silence logger |
@eromoe, I have this successfully blocking the output across multiple processes. |
Using the wrapper code, I was able to suppress INFO logs but is there a way to stop WARNING logs too? I tried setting the log level to ERROR but still WARNING logs appear. logging.getLogger('fbprophet').setLevel(logging.ERROR) |
@ShreyasJothish this should do it.
|
@RonanFelipe Use the suppression class given above from @randlet #223 (comment) Then use: import logging
from fbprophet import Prophet
logging.getLogger('fbprophet').setLevel(logging.WARNING)
model = Prophet()
with self.suppress_stdout_stderr():
model.fit(fit_data) |
Thanks @mattc-eostar, it worked. |
Running the code proposed by @randlet solved it for me thank you so much. However running this on AWS lambda sometimes gives me this error multiple times: Can anyone help? |
@CrashLaker did you see my revised code which addresses running out of file descriptors here: #223 (comment) |
Is there a workaround to suppress stan output in R? |
thanks it worked |
It didn't work for me while I am using the cross_validation while model fitting using dask, Does anyone know a workaround for that thing? I was using this like this.
|
Any progress on getting a module level option? |
just wanted to point out that Facebook has since changed the naming of the module, so the above code isn't working properly anymore, i have taken liberty to modify it to my own use (I'm calling prophet inside a function on multiple cores using multiprocessing module), below is my code:
i hope it helps anyone who wonders here for the same issue. |
|
FYI, the previous class
|
Hi, I have class suppress_stdout_stderr and worked for me, but I would like to stop it. `class suppress_stdout_stderr(object):
|
I don't think you need to open from types import TracebackType
from typing import Union
class SilentStdoutStderr(object):
"""
Context manager to temporarily silence stdout and stderr. Use with `with`.
"""
stdout, stderr = sys.__stdout__.fileno(), sys.__stderr__.fileno()
def __enter__(self) -> None:
self.devnull = os.open(os.devnull, os.O_RDWR)
self.orig_stdout, self.orig_stderr = os.dup(self.stdout), os.dup(self.stderr)
# point stdout, stderr to /dev/null
os.dup2(self.devnull, self.stdout)
os.dup2(self.devnull, self.stderr)
def __exit__(
self,
exc_type: Union[type[BaseException], None],
exc_val: Union[BaseException, None],
exc_tb: Union[TracebackType, None],
) -> None:
print(flush=True)
# restore stdout, stderr back
os.dup2(self.orig_stdout, self.stdout)
os.dup2(self.orig_stderr, self.stderr)
# close all file descriptors
for file in [self.devnull, self.orig_stdout, self.orig_stderr]:
os.close(file) But this is not important, both work anyway. However, I managed to silence logging with just: import logging
logging.getLogger("prophet").setLevel(logging.WARNING)
logging.getLogger("cmdstanpy").disabled=True |
I want to revert it back to see log, how can I do that? |
Thank you @samposm what you quoted worked for me as well: import logging
logging.getLogger("prophet").setLevel(logging.WARNING)
logging.getLogger("cmdstanpy").disabled=True |
Summary: this is local fixing of prophet issue facebook/prophet#223 (comment) as we are struggling of unneceassary stan logs. I've added parameter to turn these stan logs off with default as True, with this logs debugablity is struggling Differential Revision: D51322580 fbshipit-source-id: 5039b91b3fa4baa4a6aa5b7bba17bcc71032fa18
Thanks sir, saved a lot of time and headache looking at the cmdstanpy logs |
Hi,
I recently started using Prophet in Python, and whilst it is working (quite well), it is printing out messages which appear to be generated by PySTAN and suppressing output from stdout, stderr, and stdin doesn't seem to stop it. Could you add an option to suppress output from PySTAN. I've attached screenshots of the output and the function I am trying to use to suppress the output which is not working:
Kind regards,
Stuart Reid
The text was updated successfully, but these errors were encountered: