GARCH11 with nonzero mean?

Sure, no problem. I found this style of implementation worked in pymc3:

    import os
    
    import arviz as az
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import pymc as pm
    
    rng = np.random.RandomState(1234)
    az.style.use("arviz-darkgrid")
    
    
    try:
        returns = pd.read_csv(os.path.join("..", "data", "SP500.csv"), index_col="Date")
    except FileNotFoundError:
        returns = pd.read_csv(pm.get_data("SP500.csv"), index_col="Date")
    
    returns["change"] = np.log(returns["Close"]).diff()
    returns = returns.dropna()
    
    
    def make_garch_volatility_model(data):
        with pm.Model(coords={"time": data.index.values}) as model:
            omega= pm.Exponential('alpha_0', 30)
            alpha_1 = pm.Uniform('alpha_1', 0, 1 )
            upper = 1- alpha_1
            beta_1 = pm.Uniform("beta_1", 0, upper)
        
            initial_vol = pm.HalfNormal("init", 1)
            garch = pm.GARCH11("volatility", omega, alpha_1, beta_1, initial_vol, dims="time", observed=data["change"])
          
            returns = pm.Normal(
                "returns", mu= 0 , sigma=np.exp(garch/2), observed=data["change"], dims="time")
        return model
    
    
    garch_vol_model = make_garch_volatility_model(returns)
    
    with garch_vol_model:
        idata = pm.sample()