Login system created with Python
Some general notes:


Global variables are usually a bad idea; state that can be accessed from everywhere is hard to read and debug because you have no idea what random function might modify it.  It's extra difficult here because your globals are declared in different places.
The standard way of handling errors in Python is to raise an exception that can be caught and handled.
Long sequences of if/elif are usually an indication that your logic can either be simplified or split up.


Here's how I might suggest writing your start and register functions, using exceptions to handle errors, a lookup table to handle dispatching your different functions, and a single state object that collects all the random global variables:

from typing import NamedTuple

class LoginState(NamedTuple):
    admin: str
    adminpass: str
    user: str
    pass: str        

def start() -&gt; None:
    state = LoginState("Max", "Luo", "", "")
    print("Welcome, please choose what to do")
    menu = {
        'register': register
        'login': username
        'admin': username
    }
    choice = input('register/login ')
    try:
        menu[choice](state)
    except:
        problems()

def register(state: LoginState) -&gt; None:
    state.user = input('Please register your username : ')
    state.pass = input('Please register your password : ')
    menu = {
        "Y": register
        "N": username
    }
    choice = input('Do you want to register another account? Y/N : ')
    menu[choice](state)


Defining your state as a type means that it's easier to refactor -- for example, suppose you realize that your register logic overwrites the username and what you actually want to do is be able to have more than one!  You could change user and pass into a collection (like a Dict, say), and use mypy to tell you all the places in your program that those attributes are used so you can make the appropriate updates.  If they're defined as globals, it's a lot more difficult to make sure you've updated all the places where they're used.

The menu dict is IMO a little easier to expand (and read) than the big chain of if/elif, by providing a single obvious place where the menu options are defined.

Having problems() be an exception handler means that not only does it catch the case where the user inputs an invalid command (this will cause menu[choice] to raise an IndexError), but it will also catch any unhandled exceptions raised by your other functions, so those functions don't need to call problems() themselves; all they have to do is raise an exception and the control flow will end up right here.  In the case of register() I didn't have to do anything with the error case, because if an exception is raised there I know that it will be caught in start().

Since the "present menu, make selection" pattern is probably going to be repeated a few times in this program, I might want to make that into a function as well:

def menu_prompt(
    menu: Dict[Text, Callable[[State], None]], 
    prompt: str,
    state: LoginState
) -&gt; None:
    choice = input(prompt)
    menu[choice](state)


and now this:

    menu = {
        'register': register
        'login': username
        'admin': username
    }
    choice = input('register/login ')
    try:
        menu[choice](state)
    except:
        problems()


becomes:

try:
    menu_prompt({
        'register': register
        'login': username
        'admin': username
    }, 'register/login ', state)
except:
    problems()