Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apple Silicon M1 Cannot convert MPS Tensor to float64 #1019

Closed
traderpedroso opened this issue Aug 18, 2022 · 8 comments
Closed

Apple Silicon M1 Cannot convert MPS Tensor to float64 #1019

traderpedroso opened this issue Aug 18, 2022 · 8 comments
Labels
bug Something isn't working duplicate This issue or pull request already exists more information needed Please fill the issue template completely trading warning Trading with RL is usually a bad idea

Comments

@traderpedroso
Copy link

how could i convert to float32? on pure torch was simple, just converting tensor to dtype=torch.float32

full error

TypeError: Cannot convert a MPS Tensor to float64 dtype as the MPS framework doesn't support float64. Please use float32 instead.

@traderpedroso traderpedroso added the bug Something isn't working label Aug 18, 2022
@araffin araffin added the duplicate This issue or pull request already exists label Aug 18, 2022
@araffin
Copy link
Member

araffin commented Aug 18, 2022

Duplicate of #914 and also related more to PyTorch than SB3...

@araffin araffin closed this as completed Aug 18, 2022
@traderpedroso
Copy link
Author

Duplicate of #914 and also related more to PyTorch than SB3...

Its a different topic! MPS framework only support float32 add dtype=th.float32 on utils.py

def obs_as_tensor(
    obs: Union[np.ndarray, Dict[Union[str, int], np.ndarray]], device: th.device
) -> Union[th.Tensor, TensorDict]:
    """
    Moves the observation to the given device.

    :param obs:
    :param device: PyTorch device
    :return: PyTorch tensor of the observation on a desired device.
    """
    if isinstance(obs, np.ndarray):
        return th.as_tensor(obs, dtype=th.float32).to(device)
    elif isinstance(obs, dict):
        return {key: th.as_tensor(_obs).to(device) for (key, _obs) in obs.items()}
    else:
        raise Exception(f"Unrecognized type of observation {type(obs)}")

@araffin
Copy link
Member

araffin commented Aug 19, 2022

i assume you are using a custom env? (please fill the issue template completely)
a solution would be a gym wrapper that cast observations to float64.

@araffin araffin added the more information needed Please fill the issue template completely label Aug 19, 2022
@traderpedroso
Copy link
Author

i assume you are using a custom env? (please fill the issue template completely)
a solution would be a gym wrapper that cast observations to float64.

yes using gym_anytrading

import gym
import gym_anytrading
from stable_baselines3.ppo.policies import MlpPolicy
from stable_baselines3 import A2C, PPO
from stable_baselines3.common.evaluation import evaluate_policy
from stable_baselines3.common.env_util import make_vec_env
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import quantstats as qs


df = pd.read_csv("tickers.csv")

f = df.copy()[['open', 'high', 'low', 'close', 'volume']]
df = df.reset_index()
df.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume']
df = df.set_index('Date')


df.isnull().sum().sum() # there are no nans
df.fillna(method="ffill", inplace=True)
df = df.loc[~df.index.duplicated(keep = 'first')]   
df = df.dropna()
df = df.fillna(method="ffill")
df = df.dropna()
df = df.astype('float32')


window_size = 50
start_index = window_size
end_index = len(df)


def create_env(df, start_index, end_index, window_size):
    env = gym.make('forex-v0', df=df,  frame_bound=(start_index,
                   end_index), window_size=window_size)
    env.trade_fee = 0.01
    return env


def env_maker():
    return create_env(df, start_index, end_index, window_size)

env = make_vec_env(lambda: env_maker(), n_envs=1000) # 1000
model = PPO(MlpPolicy, env, device="mps", verbose=1) # PPO(MlpPolicy, env, verbose=1)

# Random evolute before training
mean_reward, std_reward = evaluate_policy(model, env, n_eval_episodes=10)
print(f"mean_reward:{mean_reward:.2f} +/- {std_reward:.2f}")

OUTPUT

TypeError: Cannot convert a MPS Tensor to float64 dtype as the MPS framework doesn't support float64. Please use float32 instead.

@araffin
Copy link
Member

araffin commented Aug 19, 2022

could you confirm that using a wrapper that cast observations to float32 (also for obs space) solve this issue ?

@araffin araffin added the trading warning Trading with RL is usually a bad idea label Aug 19, 2022
@traderpedroso
Copy link
Author

traderpedroso commented Aug 19, 2022

could you confirm that using a wrapper that cast observations to float32 (also for obs space) solve this issue ?

Yes, I did it!
found out float64 won work with metal API as I said here #914, and thank you for your warning I want to use it only for portfolio manager calculate position size base volatility

@charliemagee
Copy link

I found a workaround on M1 Max. Switched to 3D animation mode. Used Zoe "Depth Algorithm." Unchecked "Use depth warping."

@TimEyerish
Copy link

I just had similar happen. I shortened prompts and switched models, it's working again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists more information needed Please fill the issue template completely trading warning Trading with RL is usually a bad idea
Projects
None yet
Development

No branches or pull requests

4 participants