Well, opts
serves obviously as a wrapper for global variables, and the code seems to be written in procedural style, all input and output of each function passed through global variables.
Refactoring here should go as in any other programming language when encountering such style:
First (most important): don't refactor anything for which there is no real necessity to change. When the code is running well, and you don't have a requirement to add something, leave it that way. Only focus on parts of the code base where you have to fix bugs, need to add new features, or need to optimize.
Second: make sure you have enough automated tests for the program. You will definitely break something, so better invest some time into writing regressions tests. These don't need to be unit tests, but your tests should have some reproducible input and some recorded, validated output which is known to be "correct", for a representative sets of use cases. For a non-typesafe language like Python this is even more important since there is no compiler preventing you from typos introduced by refactorings.
And for the refactoring itself: as a start, get rid of as many global variables as possible. Instead, introduce explicit input parameters and return values for each functions, and restrict their usage to the smallest possible scope possible. Functions with no side effects (or at least less side effects), and functions which don't rely on side effects are way easier to reason about and to maintain as functions which do cause or rely on side effects.
Note this can be only a start. You will probably have to apply lots of more of the standard refactoring techniques you find in books like Fowler's "Refactoring" book and Feathers' "Working Effectively with Legacy Code" book. Also have a look into one of our old, but timeless questions on this site: I've inherited 200K lines of spaghetti code -- what now?.
Good luck!
TLDR; No, there is no easy way. But there are standard approaches, which require hard work, as ever.