You don't have to worry about hash_funcs! Just prefix your arguments with an underscore to ignore them.
Singleton objects can be used concurrently by every user connected to your app, and you are responsible for ensuring that @st.singleton objects are thread-safe. (Most objects you'd want to stick inside an @st.singleton annotation are probably already safe—but you should verify this.)
Which to use: memo or singleton?
Decide between @st.experimental_memo and @st.experimental_singleton based on your function's return type. Functions that return data should use memo. Functions that return non-data objects should use singleton.
For example:
Dataframe computation (pandas, numpy, etc): this is data—use memo
Storing downloaded data: memo
Calculating pi to n digits: memo
Tensorflow session: this is a non-data object—use singleton
