Add varaitional inference

TODO: split tasks