diff --git a/configs/env/default.yaml b/configs/env/default.yaml index aa09a8cb..1debdb1f 100644 --- a/configs/env/default.yaml +++ b/configs/env/default.yaml @@ -3,4 +3,4 @@ name: tsp generator_params: num_loc: 20 - loc_distribution: uniform + loc_distribution: uniform \ No newline at end of file diff --git a/configs/env/fjsp.yaml b/configs/env/fjsp/10j-5m.yaml similarity index 100% rename from configs/env/fjsp.yaml rename to configs/env/fjsp/10j-5m.yaml diff --git a/configs/env/fjsp/15j-10m.yaml b/configs/env/fjsp/15j-10m.yaml new file mode 100644 index 00000000..7df35842 --- /dev/null +++ b/configs/env/fjsp/15j-10m.yaml @@ -0,0 +1,13 @@ +_target_: rl4co.envs.FJSPEnv +name: fjsp + +generator_params: + num_jobs: 15 + num_machines: 10 + min_ops_per_job: 8 + max_ops_per_job: 12 + min_processing_time: 1 + max_processing_time: 20 + min_eligible_ma_per_op: 1 + +data_dir: ${paths.root_dir}/data/fjsp diff --git a/configs/env/fjsp/20j-10m.yaml b/configs/env/fjsp/20j-10m.yaml new file mode 100644 index 00000000..4574f22a --- /dev/null +++ b/configs/env/fjsp/20j-10m.yaml @@ -0,0 +1,13 @@ +_target_: rl4co.envs.FJSPEnv +name: fjsp + +generator_params: + num_jobs: 20 + num_machines: 10 + min_ops_per_job: 8 + max_ops_per_job: 12 + min_processing_time: 1 + max_processing_time: 20 + min_eligible_ma_per_op: 1 + +data_dir: ${paths.root_dir}/data/fjsp diff --git a/configs/env/fjsp/20j-5m.yaml b/configs/env/fjsp/20j-5m.yaml new file mode 100644 index 00000000..04e7f8d7 --- /dev/null +++ b/configs/env/fjsp/20j-5m.yaml @@ -0,0 +1,13 @@ +_target_: rl4co.envs.FJSPEnv +name: fjsp + +generator_params: + num_jobs: 20 + num_machines: 5 + min_ops_per_job: 4 + max_ops_per_job: 6 + min_processing_time: 1 + max_processing_time: 20 + min_eligible_ma_per_op: 1 + +data_dir: ${paths.root_dir}/data/fjsp diff --git a/configs/env/jssp/10j-10m.yaml b/configs/env/jssp/10j-10m.yaml new file mode 100644 index 00000000..d7e13964 --- /dev/null +++ b/configs/env/jssp/10j-10m.yaml @@ -0,0 +1,11 @@ +_target_: rl4co.envs.JSSPEnv +name: jssp + +generator_params: + num_jobs: 10 + num_machines: 10 + min_processing_time: 1 + max_processing_time: 99 + +data_dir: ${paths.root_dir}/data/jssp/taillard +test_file: ${env.generator_params.num_jobs}j_${env.generator_params.num_machines}m \ No newline at end of file diff --git a/configs/env/jssp/15j-15m.yaml b/configs/env/jssp/15j-15m.yaml new file mode 100644 index 00000000..16d20dc2 --- /dev/null +++ b/configs/env/jssp/15j-15m.yaml @@ -0,0 +1,11 @@ +_target_: rl4co.envs.JSSPEnv +name: jssp + +generator_params: + num_jobs: 15 + num_machines: 15 + min_processing_time: 1 + max_processing_time: 99 + +data_dir: ${paths.root_dir}/data/jssp/taillard +test_file: ${env.generator_params.num_jobs}j_${env.generator_params.num_machines}m \ No newline at end of file diff --git a/configs/env/jssp/20j-20m.yaml b/configs/env/jssp/20j-20m.yaml new file mode 100644 index 00000000..b3373d85 --- /dev/null +++ b/configs/env/jssp/20j-20m.yaml @@ -0,0 +1,11 @@ +_target_: rl4co.envs.JSSPEnv +name: jssp + +generator_params: + num_jobs: 20 + num_machines: 20 + min_processing_time: 1 + max_processing_time: 99 + +data_dir: ${paths.root_dir}/data/jssp/taillard +test_file: ${env.generator_params.num_jobs}j_${env.generator_params.num_machines}m \ No newline at end of file diff --git a/configs/env/jssp/6j-6m.yaml b/configs/env/jssp/6j-6m.yaml new file mode 100644 index 00000000..d7cc4170 --- /dev/null +++ b/configs/env/jssp/6j-6m.yaml @@ -0,0 +1,11 @@ +_target_: rl4co.envs.JSSPEnv +name: jssp + +generator_params: + num_jobs: 6 + num_machines: 6 + min_processing_time: 1 + max_processing_time: 99 + +data_dir: ${paths.root_dir}/data/jssp/taillard +test_file: ${env.generator_params.num_jobs}j_${env.generator_params.num_machines}m \ No newline at end of file diff --git a/configs/experiment/routing/tsp-stepwise-ppo.yaml b/configs/experiment/routing/tsp-stepwise-ppo.yaml new file mode 100644 index 00000000..678223ec --- /dev/null +++ b/configs/experiment/routing/tsp-stepwise-ppo.yaml @@ -0,0 +1,57 @@ +# @package _global_ + +defaults: + - override /model: l2d.yaml + - override /callbacks: default.yaml + - override /trainer: default.yaml + - override /logger: wandb.yaml + +env: + _target_: rl4co.envs.TSPEnv4PPO + generator_params: + num_loc: 20 + +logger: + wandb: + project: "rl4co" + tags: ["am-stepwise-ppo", "${env.name}"] + group: ${env.name}${env.generator_params.num_loc} + name: ppo-${env.name}${env.generator_params.num_loc} + +trainer: + max_epochs: 10 + precision: 32-true + +embed_dim: 256 +num_heads: 8 +model: + _target_: rl4co.models.StepwisePPO + policy: + _target_: rl4co.models.L2DPolicy4PPO + decoder: + _target_: rl4co.models.zoo.l2d.decoder.L2DDecoder + env_name: ${env.name} + embed_dim: ${embed_dim} + feature_extractor: + _target_: rl4co.models.zoo.am.encoder.AttentionModelEncoder + embed_dim: ${embed_dim} + num_heads: ${num_heads} + num_layers: 4 + normalization: "batch" + env_name: "tsp" + actor: + _target_: rl4co.models.zoo.l2d.decoder.AttnActor + embed_dim: ${embed_dim} + num_heads: ${num_heads} + env_name: ${env.name} + embed_dim: ${embed_dim} + env_name: ${env.name} + het_emb: False + batch_size: 512 + mini_batch_size: 512 + train_data_size: 20000 + val_data_size: 1_000 + test_data_size: 1_000 + reward_scale: scale + optimizer_kwargs: + lr: 1e-4 \ No newline at end of file diff --git a/configs/experiment/scheduling/am-pomo.yaml b/configs/experiment/scheduling/am-pomo.yaml new file mode 100644 index 00000000..a3d2cde7 --- /dev/null +++ b/configs/experiment/scheduling/am-pomo.yaml @@ -0,0 +1,23 @@ +# @package _global_ + +defaults: + - scheduling/base + +logger: + wandb: + tags: ["am-pomo", "${env.name}"] + name: "am-pomo-${env.name}-${env.generator_params.num_jobs}j-${env.generator_params.num_machines}m" + +model: + _target_: rl4co.models.POMO + policy: + _target_: rl4co.models.L2DAttnPolicy + env_name: ${env.name} + scaling_factor: ${scaling_factor} + batch_size: 64 + num_starts: 10 + num_augment: 0 + baseline: "shared" + metrics: + val: ["reward", "max_reward"] + test: ${model.metrics.val} diff --git a/configs/experiment/scheduling/am-ppo.yaml b/configs/experiment/scheduling/am-ppo.yaml new file mode 100644 index 00000000..c5d38eb1 --- /dev/null +++ b/configs/experiment/scheduling/am-ppo.yaml @@ -0,0 +1,56 @@ +# @package _global_ + +defaults: + - scheduling/base + +logger: + wandb: + tags: ["am-ppo", "${env.name}"] + name: "am-ppo-${env.name}-${env.generator_params.num_jobs}j-${env.generator_params.num_machines}m" + +embed_dim: 256 +num_heads: 8 + +model: + _target_: rl4co.models.StepwisePPO + policy: + _target_: rl4co.models.L2DPolicy4PPO + decoder: + _target_: rl4co.models.zoo.l2d.decoder.L2DDecoder + env_name: ${env.name} + embed_dim: ${embed_dim} + feature_extractor: + _target_: rl4co.models.zoo.matnet.matnet_w_sa.Encoder + embed_dim: ${embed_dim} + num_heads: ${num_heads} + num_layers: 4 + normalization: "batch" + init_embedding: + _target_: rl4co.models.nn.env_embeddings.init.FJSPMatNetInitEmbedding + embed_dim: ${embed_dim} + scaling_factor: ${scaling_factor} + actor: + _target_: rl4co.models.zoo.l2d.decoder.L2DAttnActor + embed_dim: ${embed_dim} + num_heads: ${num_heads} + env_name: ${env.name} + scaling_factor: ${scaling_factor} + stepwise: True + env_name: ${env.name} + embed_dim: ${embed_dim} + scaling_factor: ${scaling_factor} + het_emb: True + batch_size: 128 + val_batch_size: 512 + test_batch_size: 64 + # Song et al use 1000 iterations over batches of 20 = 20_000 + # We train 10 epochs on a set of 2000 instance = 20_000 + train_data_size: 2000 + mini_batch_size: 512 + reward_scale: scale + optimizer_kwargs: + lr: 1e-4 + +env: + stepwise_reward: True + _torchrl_mode: True \ No newline at end of file diff --git a/configs/experiment/scheduling/base.yaml b/configs/experiment/scheduling/base.yaml new file mode 100644 index 00000000..e84f95fd --- /dev/null +++ b/configs/experiment/scheduling/base.yaml @@ -0,0 +1,38 @@ +# @package _global_ + +defaults: + - override /model: l2d.yaml + - override /callbacks: default.yaml + - override /trainer: default.yaml + - override /logger: wandb.yaml + +logger: + wandb: + project: "rl4co" + log_model: "all" + group: "${env.name}-${env.generator_params.num_jobs}-${env.generator_params.num_machines}" + tags: ??? + name: ??? + +trainer: + max_epochs: 10 + # NOTE for some reason l2d is extremely sensitive to precision + # ONLY USE 32-true for l2d! + precision: 32-true + +seed: 12345678 + +scaling_factor: 20 + +model: + _target_: ??? + batch_size: ??? + train_data_size: 2_000 + val_data_size: 1_000 + test_data_size: 1_000 + optimizer_kwargs: + lr: 1e-4 + weight_decay: 1e-6 + lr_scheduler: "ExponentialLR" + lr_scheduler_kwargs: + gamma: 0.95 diff --git a/configs/experiment/scheduling/gnn-ppo.yaml b/configs/experiment/scheduling/gnn-ppo.yaml new file mode 100644 index 00000000..d9c04856 --- /dev/null +++ b/configs/experiment/scheduling/gnn-ppo.yaml @@ -0,0 +1,35 @@ +# @package _global_ + +defaults: + - scheduling/base + +logger: + wandb: + tags: ["gnn-ppo", "${env.name}"] + name: "gnn-ppo-${env.name}-${env.generator_params.num_jobs}j-${env.generator_params.num_machines}m" + +# params from Song et al. +model: + _target_: rl4co.models.L2DPPOModel + policy_kwargs: + embed_dim: 128 + num_encoder_layers: 3 + scaling_factor: ${scaling_factor} + max_grad_norm: 1 + ppo_epochs: 3 + het_emb: False + batch_size: 128 + val_batch_size: 512 + test_batch_size: 64 + mini_batch_size: 512 + reward_scale: scale + optimizer_kwargs: + lr: 1e-4 + +trainer: + max_epochs: 10 + + +env: + stepwise_reward: True + _torchrl_mode: True \ No newline at end of file diff --git a/configs/experiment/scheduling/hgnn-pomo.yaml b/configs/experiment/scheduling/hgnn-pomo.yaml new file mode 100644 index 00000000..eb688c03 --- /dev/null +++ b/configs/experiment/scheduling/hgnn-pomo.yaml @@ -0,0 +1,27 @@ +# @package _global_ + +defaults: + - scheduling/base + +logger: + wandb: + tags: ["hgnn-pomo", "${env.name}"] + name: "hgnn-pomo-${env.name}-${env.generator_params.num_jobs}j-${env.generator_params.num_machines}m" + +model: + _target_: rl4co.models.POMO + policy: + _target_: rl4co.models.L2DPolicy + env_name: ${env.name} + embed_dim: 256 + num_encoder_layers: 3 + stepwise_encoding: False + scaling_factor: ${scaling_factor} + het_emb: True + num_starts: 10 + batch_size: 64 + num_augment: 0 + baseline: "shared" + metrics: + val: ["reward", "max_reward"] + test: ${model.metrics.val} \ No newline at end of file diff --git a/configs/experiment/scheduling/hgnn-ppo.yaml b/configs/experiment/scheduling/hgnn-ppo.yaml new file mode 100644 index 00000000..8e3a62d8 --- /dev/null +++ b/configs/experiment/scheduling/hgnn-ppo.yaml @@ -0,0 +1,35 @@ +# @package _global_ + +defaults: + - scheduling/base + +logger: + wandb: + tags: ["hgnn-ppo", "${env.name}"] + name: "hgnn-ppo-${env.name}-${env.generator_params.num_jobs}j-${env.generator_params.num_machines}m" + +# params from Song et al. +model: + _target_: rl4co.models.L2DPPOModel + policy_kwargs: + embed_dim: 128 + num_encoder_layers: 3 + scaling_factor: ${scaling_factor} + max_grad_norm: 1 + ppo_epochs: 3 + het_emb: True + batch_size: 128 + val_batch_size: 512 + test_batch_size: 64 + mini_batch_size: 512 + reward_scale: scale + optimizer_kwargs: + lr: 1e-4 + +trainer: + max_epochs: 10 + + +env: + stepwise_reward: True + _torchrl_mode: True \ No newline at end of file diff --git a/configs/experiment/scheduling/matnet-pomo.yaml b/configs/experiment/scheduling/matnet-pomo.yaml new file mode 100644 index 00000000..bab68644 --- /dev/null +++ b/configs/experiment/scheduling/matnet-pomo.yaml @@ -0,0 +1,38 @@ +# @package _global_ + +defaults: + - scheduling/base + +logger: + wandb: + tags: ["matnet-pomo", "${env.name}"] + name: "matnet-pomo-${env.name}-${env.generator_params.num_jobs}j-${env.generator_params.num_machines}m" + +embed_dim: 256 + +model: + _target_: rl4co.models.POMO + policy: + _target_: rl4co.models.L2DPolicy + encoder: + _target_: rl4co.models.zoo.matnet.matnet_w_sa.Encoder + embed_dim: ${embed_dim} + num_heads: 8 + num_layers: 4 + normalization: "batch" + init_embedding: + _target_: rl4co.models.nn.env_embeddings.init.FJSPMatNetInitEmbedding + embed_dim: ${embed_dim} + scaling_factor: ${scaling_factor} + env_name: ${env.name} + embed_dim: ${embed_dim} + stepwise_encoding: False + het_emb: True + scaling_factor: ${scaling_factor} + batch_size: 64 + num_starts: 10 + num_augment: 0 + baseline: "shared" + metrics: + val: ["reward", "max_reward"] + test: ${model.metrics.val} diff --git a/configs/experiment/scheduling/matnet-ppo.yaml b/configs/experiment/scheduling/matnet-ppo.yaml new file mode 100644 index 00000000..f0e30e3b --- /dev/null +++ b/configs/experiment/scheduling/matnet-ppo.yaml @@ -0,0 +1,48 @@ +# @package _global_ + +defaults: + - scheduling/base + +logger: + wandb: + tags: ["matnet-ppo", "${env.name}"] + name: "matnet-ppo-${env.name}-${env.generator_params.num_jobs}j-${env.generator_params.num_machines}m" + +embed_dim: 256 + +model: + _target_: rl4co.models.StepwisePPO + policy: + _target_: rl4co.models.L2DPolicy4PPO + decoder: + _target_: rl4co.models.zoo.l2d.decoder.L2DDecoder + env_name: ${env.name} + embed_dim: ${embed_dim} + het_emb: True + feature_extractor: + _target_: rl4co.models.zoo.matnet.matnet_w_sa.Encoder + embed_dim: ${embed_dim} + num_heads: 8 + num_layers: 4 + normalization: "batch" + init_embedding: + _target_: rl4co.models.nn.env_embeddings.init.FJSPMatNetInitEmbedding + embed_dim: ${embed_dim} + scaling_factor: ${scaling_factor} + env_name: ${env.name} + embed_dim: ${embed_dim} + scaling_factor: ${scaling_factor} + het_emb: True + batch_size: 128 + val_batch_size: 512 + test_batch_size: 64 + # Song et al use 1000 iterations over batches of 20 = 20_000 + # We train 10 epochs on a set of 2000 instance = 20_000 + mini_batch_size: 512 + reward_scale: scale + optimizer_kwargs: + lr: 1e-4 + +env: + stepwise_reward: True + _torchrl_mode: True \ No newline at end of file diff --git a/configs/model/hetgnn.yaml b/configs/model/hetgnn.yaml deleted file mode 100644 index 600ef49f..00000000 --- a/configs/model/hetgnn.yaml +++ /dev/null @@ -1,3 +0,0 @@ -_target_: rl4co.models.HetGNNModel - -baseline: "rollout" \ No newline at end of file diff --git a/configs/model/l2d.yaml b/configs/model/l2d.yaml new file mode 100644 index 00000000..9b93f1ee --- /dev/null +++ b/configs/model/l2d.yaml @@ -0,0 +1 @@ +_target_: rl4co.models.L2DModel \ No newline at end of file diff --git a/configs/model/matnet.yaml b/configs/model/matnet.yaml index 543de5af..6634e4a1 100644 --- a/configs/model/matnet.yaml +++ b/configs/model/matnet.yaml @@ -2,6 +2,6 @@ _target_: rl4co.models.MatNet metrics: train: ["loss", "reward", "max_reward"] - val: ["max_reward"] + val: ["reward", "max_reward"] test: ["max_reward"] log_on_step: True \ No newline at end of file diff --git a/examples/other/2-scheduling.ipynb b/examples/other/2-scheduling.ipynb index ee5de19f..4c4c029e 100644 --- a/examples/other/2-scheduling.ipynb +++ b/examples/other/2-scheduling.ipynb @@ -13,9 +13,18 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The autoreload extension is already loaded. To reload it, use:\n", + " %reload_ext autoreload\n" + ] + } + ], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", @@ -29,16 +38,16 @@ "import networkx as nx\n", "import matplotlib.pyplot as plt\n", "from rl4co.envs import FJSPEnv\n", - "from rl4co.models.zoo.hetgnn import HetGNNModel\n", - "from rl4co.models.zoo.hetgnn.policy import HetGNNPolicy\n", - "from rl4co.models.zoo.hetgnn.encoder import HetGNNEncoder\n", - "from rl4co.models.zoo.hetgnn.decoder import HetGNNDecoder\n", + "from rl4co.models.zoo.l2d import L2DModel\n", + "from rl4co.models.zoo.l2d.policy import L2DPolicy\n", + "from rl4co.models.zoo.l2d.decoder import L2DDecoder\n", + "from rl4co.models.nn.graph.hgnn import HetGNNEncoder\n", "from rl4co.utils.trainer import RL4COTrainer" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -56,7 +65,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -81,12 +90,12 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -169,7 +178,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -192,7 +201,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -220,16 +229,16 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[ 0, 4, 9, 14, 20, 25, 29, 33, 37, 42]])" + "tensor([[ 0, 5, 10, 16, 20, 24, 29, 34, 40, 44]])" ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -241,7 +250,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -253,7 +262,7 @@ } ], "source": [ - "decoder = HetGNNDecoder(embed_dim=32)\n", + "decoder = L2DDecoder(env_name=env.name, embed_dim=32)\n", "logits, mask = decoder(td, (ma_emb, op_emb), num_starts=0)\n", "# (1 + num_jobs * num_machines)\n", "print(logits.shape)" @@ -261,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -290,7 +299,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -304,7 +313,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -349,9 +358,83 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/luttmann/opt/miniconda3/envs/rl4co/lib/python3.9/site-packages/lightning/pytorch/utilities/parsing.py:198: Attribute 'env' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['env'])`.\n", + "/Users/luttmann/opt/miniconda3/envs/rl4co/lib/python3.9/site-packages/lightning/pytorch/utilities/parsing.py:198: Attribute 'policy' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['policy'])`.\n", + "/Users/luttmann/opt/miniconda3/envs/rl4co/lib/python3.9/site-packages/lightning/pytorch/trainer/connectors/accelerator_connector.py:551: You passed `Trainer(accelerator='cpu', precision='16-mixed')` but AMP with fp16 is not supported on CPU. Using `precision='bf16-mixed'` instead.\n", + "Using bfloat16 Automatic Mixed Precision (AMP)\n", + "GPU available: False, used: False\n", + "TPU available: False, using: 0 TPU cores\n", + "IPU available: False, using: 0 IPUs\n", + "HPU available: False, using: 0 HPUs\n", + "/Users/luttmann/opt/miniconda3/envs/rl4co/lib/python3.9/site-packages/lightning/pytorch/trainer/connectors/logger_connector/logger_connector.py:67: Starting from v1.9.0, `tensorboardX` has been removed as a dependency of the `lightning.pytorch` package, due to potential conflicts with other packages in the ML ecosystem. For this reason, `logger=True` will use `CSVLogger` as the default logger, unless the `tensorboard` or `tensorboardX` packages are found. Please `pip install lightning[extra]` or one of them to enable TensorBoard support by default\n", + "Missing logger folder: /Users/luttmann/Documents/Diss/Repos/nco/ai4co/rl4co/examples/other/lightning_logs\n", + "val_file not set. Generating dataset instead\n", + "test_file not set. Generating dataset instead\n", + "\n", + " | Name | Type | Params\n", + "--------------------------------------------\n", + "0 | env | FJSPEnv | 0 \n", + "1 | policy | L2DPolicy | 15.9 K\n", + "2 | baseline | WarmupBaseline | 15.9 K\n", + "--------------------------------------------\n", + "31.9 K Trainable params\n", + "0 Non-trainable params\n", + "31.9 K Total params\n", + "0.127 Total estimated model params size (MB)\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c543880423f84865a05170d16a5aa6fd", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Sanity Checking: | | 0/? [00:00 TensorDict: # Sample penalty penalty = self.penalty_sampler.sample((*batch_size, self.num_loc)) - # Sampel prize + # Take uniform prizes + # Now expectation is 0.5 so expected total prize is n / 2, we want to force to visit approximately half of the nodes + # so the constraint will be that total prize >= (n / 2) / 2 = n / 4 + # equivalently, we divide all prizes by n / 4 and the total prize should be >= 1 deterministic_prize = self.deterministic_prize_sampler.sample( (*batch_size, self.num_loc) ) + + # In the deterministic setting, the stochastic_prize is not used and the deterministic prize is known + # In the stochastic setting, the deterministic prize is the expected prize and is known up front but the + # stochastic prize is only revealed once the node is visited + # Stochastic prize is between (0, 2 * expected_prize) such that E(stochastic prize) = E(deterministic_prize) stochastic_prize = self.stochastic_prize_sampler.sample( (*batch_size, self.num_loc) - ) + ) * deterministic_prize return TensorDict( { diff --git a/rl4co/envs/routing/tsp/env.py b/rl4co/envs/routing/tsp/env.py index eb1c3402..0ea92569 100644 --- a/rl4co/envs/routing/tsp/env.py +++ b/rl4co/envs/routing/tsp/env.py @@ -11,7 +11,7 @@ ) from rl4co.envs.common.base import RL4COEnvBase -from rl4co.utils.ops import gather_by_index, get_tour_length +from rl4co.utils.ops import gather_by_index, get_distance, get_tour_length from rl4co.utils.pylogger import get_pylogger from .generator import TSPGenerator @@ -167,5 +167,62 @@ def check_solution_validity(td: TensorDict, actions: torch.Tensor): ).all(), "Invalid tour" @staticmethod - def render(td: TensorDict, actions: torch.Tensor=None, ax = None): + def render(td: TensorDict, actions: torch.Tensor = None, ax=None): return render(td, actions, ax) + + +class DenseRewardTSPEnv(TSPEnv): + """ + This is an experimental version of the TSPEnv to be used with stepwise PPO. That is + this environment defines a stepwise reward function for the TSP which is the distance added + to the current tour by the given action. + """ + + def __init__( + self, generator: TSPGenerator = None, generator_params: dict = {}, **kwargs + ): + super().__init__( + generator, + generator_params, + check_solution=False, + _torchrl_mode=True, + **kwargs, + ) + + def _step(self, td): + last_node = td["current_node"].clone() + current_node = td["action"] + + first_node = current_node if td["i"].all() == 0 else td["first_node"] + + # # Set not visited to 0 (i.e., we visited the node) + available = td["action_mask"].scatter( + -1, current_node.unsqueeze(-1).expand_as(td["action_mask"]), 0 + ) + + # We are done there are no unvisited locations + done = torch.sum(available, dim=-1) == 0 + + # calc stepwise reward + last_node_loc = gather_by_index(td["locs"], last_node) + curr_node_loc = gather_by_index(td["locs"], current_node) + reward = get_distance(last_node_loc, curr_node_loc)[:, None] + + td.update( + { + "first_node": first_node, + "current_node": current_node, + "i": td["i"] + 1, + "action_mask": available, + "reward": reward, + "done": done, + }, + ) + return td + + def _get_reward(self, td, actions=None) -> TensorDict: + if actions is not None: + # Gather locations in order of tour and return distance between them (i.e., -reward) + locs_ordered = gather_by_index(td["locs"], actions) + return -get_tour_length(locs_ordered) + return -td["reward"] diff --git a/rl4co/envs/scheduling/__init__.py b/rl4co/envs/scheduling/__init__.py index 897ee755..40b5571e 100644 --- a/rl4co/envs/scheduling/__init__.py +++ b/rl4co/envs/scheduling/__init__.py @@ -1,3 +1,5 @@ from rl4co.envs.scheduling.ffsp.env import FFSPEnv from rl4co.envs.scheduling.fjsp.env import FJSPEnv + +# from rl4co.envs.scheduling.jssp.env import JSSPEnv from rl4co.envs.scheduling.smtwtp.env import SMTWTPEnv diff --git a/rl4co/envs/scheduling/ffsp/env.py b/rl4co/envs/scheduling/ffsp/env.py index f3037e18..da8eff24 100644 --- a/rl4co/envs/scheduling/ffsp/env.py +++ b/rl4co/envs/scheduling/ffsp/env.py @@ -13,11 +13,10 @@ UnboundedDiscreteTensorSpec, ) -from .generator import FFSPGenerator -from .render import render - from rl4co.envs.common.base import RL4COEnvBase +from .generator import FFSPGenerator + class FFSPEnv(RL4COEnvBase): """Flexible Flow Shop Problem (FFSP) environment. @@ -58,7 +57,7 @@ def __init__( generator_params: dict = {}, **kwargs, ): - super().__init__(**kwargs) + super().__init__(check_solution=False, **kwargs) if generator is None: generator = FFSPGenerator(**generator_params) self.generator = generator @@ -283,9 +282,7 @@ def _reset( # Init index record tensor time_idx = torch.zeros(size=(*batch_size,), dtype=torch.long, device=device) - sub_time_idx = torch.zeros( - size=(*batch_size,), dtype=torch.long, device=device - ) + sub_time_idx = torch.zeros(size=(*batch_size,), dtype=torch.long, device=device) # Scheduling status information schedule = torch.full( @@ -412,7 +409,10 @@ def _make_spec(self, generator: FFSPGenerator): dtype=torch.int64, ), job_duration=UnboundedDiscreteTensorSpec( - shape=(generator.num_job + 1, generator.num_machine * generator.num_stage), + shape=( + generator.num_job + 1, + generator.num_machine * generator.num_stage, + ), dtype=torch.int64, ), shape=(), diff --git a/rl4co/envs/scheduling/fjsp/env.py b/rl4co/envs/scheduling/fjsp/env.py index 4a6a217f..dac1c8b6 100644 --- a/rl4co/envs/scheduling/fjsp/env.py +++ b/rl4co/envs/scheduling/fjsp/env.py @@ -68,6 +68,8 @@ def __init__( generator: FJSPGenerator = None, generator_params: dict = {}, mask_no_ops: bool = True, + check_mask: bool = False, + stepwise_reward: bool = False, **kwargs, ): super().__init__(check_solution=False, **kwargs) @@ -81,6 +83,8 @@ def __init__( self.num_jobs = generator.num_jobs self.n_ops_max = generator.max_ops_per_job * self.num_jobs self.mask_no_ops = mask_no_ops + self.check_mask = check_mask + self.stepwise_reward = stepwise_reward self._make_spec(self.generator) def _decode_graph_structure(self, td: TensorDict): @@ -173,13 +177,14 @@ def _reset(self, td: TensorDict = None, batch_size=None) -> TensorDict: }, ) - td_reset.set("lbs", calc_lower_bound(td_reset)) - td_reset.set("is_ready", op_is_ready(td_reset)) td_reset.set("action_mask", self.get_action_mask(td_reset)) + # add additional features to tensordict + td_reset["lbs"] = calc_lower_bound(td_reset) + td_reset = self._get_features(td_reset) return td_reset - def get_action_mask(self, td: TensorDict) -> torch.Tensor: + def _get_job_machine_availability(self, td: TensorDict): batch_size = td.size(0) # (bs, jobs, machines) @@ -200,16 +205,33 @@ def get_action_mask(self, td: TensorDict) -> torch.Tensor: td["proc_times"], td["next_op"].unsqueeze(1), dim=2, squeeze=False ).transpose(1, 2) action_mask.add_(next_ops_proc_times == 0) + return action_mask + + def get_action_mask(self, td: TensorDict) -> torch.Tensor: + # 1 indicates machine or job is unavailable at current time step + action_mask = self._get_job_machine_availability(td) if self.mask_no_ops: - no_op_mask = ~td["done"] + # masking is only allowed if instance is finished + no_op_mask = td["done"] else: - no_op_mask = ~td["job_in_process"].any(1, keepdims=True) & ~td["done"] + # if no job is currently processed and instance is not finished yet, waiting is not allowed + no_op_mask = ( + td["job_in_process"].any(1, keepdims=True) & (~td["done"]) + ) | td["done"] # flatten action mask to correspond with logit shape action_mask = rearrange(action_mask, "bs j m -> bs (j m)") # NOTE: 1 means feasible action, 0 means infeasible action - mask = torch.cat((~no_op_mask, ~action_mask), dim=1) + mask = torch.cat((no_op_mask, ~action_mask), dim=1) + return mask + def _translate_action(self, td): + """This function translates an action into a machine, job tuple.""" + selected_job = td["action"] // self.num_mas + selected_op = td["next_op"].gather(1, selected_job[:, None]).squeeze(1) + selected_machine = td["action"] % self.num_mas + return selected_job, selected_op, selected_machine + def _step(self, td: TensorDict): # cloning required to avoid inplace operation which avoids gradient backtracking td = td.clone() @@ -225,14 +247,11 @@ def _step(self, td: TensorDict): if no_op.any(): td, dones = self._transit_to_next_time(no_op, td) + # select only instances that perform a scheduling action td_op = td.masked_select(req_op) - # (#req_op) - selected_job = td_op["action"] // self.num_mas - # (#req_op) - selected_machine = td_op["action"] % self.num_mas - td_op = self._make_step(td_op, selected_job, selected_machine) - + td_op = self._make_step(td_op) + # update the tensordict td[req_op] = td_op # action mask @@ -243,11 +262,26 @@ def _step(self, td: TensorDict): td, dones = self._transit_to_next_time(step_complete, td) td.set("action_mask", self.get_action_mask(td)) step_complete = self._check_step_complete(td, dones) + if self.check_mask: + assert reduce(td["action_mask"], "bs ... -> bs", "any").all() + + if self.stepwise_reward: + # if we require a stepwise reward, the change in the calculated lower bounds could serve as such + lbs = calc_lower_bound(td) + td["reward"] = -(lbs.max(1).values - td["lbs"].max(1).values) + td["lbs"] = lbs + else: + td["lbs"] = calc_lower_bound(td) + + # add additional features to tensordict + td = self._get_features(td) + + return td + def _get_features(self, td): # after we have transitioned to a next time step, we determine which operations are ready td["is_ready"] = op_is_ready(td) - - td["lbs"] = calc_lower_bound(td) + # td["lbs"] = calc_lower_bound(td) return td @@ -259,17 +293,18 @@ def _check_step_complete(td, dones): """ return ~reduce(td["action_mask"], "bs ... -> bs", "any") & ~dones - def _make_step(self, td: TensorDict, selected_job, selected_machine) -> TensorDict: + def _make_step(self, td: TensorDict) -> TensorDict: """ Environment transition function """ batch_idx = torch.arange(td.size(0)) - td["job_in_process"][batch_idx, selected_job] = 1 + # 3*(#req_op) + selected_job, selected_op, selected_machine = self._translate_action(td) - # (#req_op) - selected_op = td["next_op"].gather(1, selected_job[:, None]).squeeze(1) + # mark job as being processed + td["job_in_process"][batch_idx, selected_job] = 1 # mark op as schedules td["op_scheduled"][batch_idx, selected_op] = True @@ -285,6 +320,23 @@ def _make_step(self, td: TensorDict, selected_job, selected_machine) -> TensorDi td["ma_assignment"][batch_idx, selected_machine, selected_op] = 1 # update the state of the selected machine td["busy_until"][batch_idx, selected_machine] = td["time"] + proc_time_of_action + # update adjacency matrices (remove edges) + td["proc_times"] = td["proc_times"].scatter( + 2, + selected_op[:, None, None].expand(-1, self.num_mas, 1), + torch.zeros_like(td["proc_times"]), + ) + td["ops_ma_adj"] = td["proc_times"].contiguous().gt(0).to(torch.float32) + td["num_eligible"] = torch.sum(td["ops_ma_adj"], dim=1) + # update the positions of an operation in the job (subtract 1 from each operation of the selected job) + td["ops_sequence_order"] = ( + td["ops_sequence_order"] - gather_by_index(td["job_ops_adj"], selected_job, 1) + ).clip(0) + # some checks + assert torch.allclose( + td["proc_times"].sum(1).gt(0).sum(1), # num ops with eligible machine + (~(td["op_scheduled"] + td["pad_mask"])).sum(1), # num unscheduled ops + ) return td @@ -333,7 +385,15 @@ def _transit_to_next_time(self, step_complete, td: TensorDict) -> TensorDict: return td, td["done"].squeeze(1) def _get_reward(self, td, actions=None) -> TensorDict: - return -td["finish_times"].masked_fill(td["pad_mask"], -torch.inf).max(1).values + if self.stepwise_reward and actions is None: + return td["reward"] + else: + assert td[ + "done" + ].all(), "Set stepwise_reward to True if you want reward prior to completion" + return ( + -td["finish_times"].masked_fill(td["pad_mask"], -torch.inf).max(1).values + ) def _make_spec(self, generator: FJSPGenerator): self.observation_spec = CompositeSpec( @@ -422,3 +482,8 @@ def select_start_nodes(self, td: TensorDict, num_starts: int): def get_num_starts(self, td): # NOTE in the paper they use N_s = 100 return 100 + + @staticmethod + def load_data(fpath, batch_size=[]): + g = FJSPFileGenerator(fpath) + return g(batch_size=batch_size) diff --git a/rl4co/envs/scheduling/fjsp/generator.py b/rl4co/envs/scheduling/fjsp/generator.py index f1ae6202..60246a50 100644 --- a/rl4co/envs/scheduling/fjsp/generator.py +++ b/rl4co/envs/scheduling/fjsp/generator.py @@ -198,6 +198,8 @@ def _generate(self, batch_size: List[int]) -> TensorDict: end_idx = self.start_idx + batch_size td = self.td[self.start_idx : end_idx] self.start_idx += batch_size + if self.start_idx >= self.num_samples: + self.start_idx = 0 return td @staticmethod @@ -210,7 +212,4 @@ def list_files(path): if os.path.isfile(os.path.join(path, f)) ] assert len(files) > 0 - files = sorted( - files, key=lambda f: int(os.path.splitext(os.path.basename(f))[0][:4]) - ) return files diff --git a/rl4co/envs/scheduling/fjsp/utils.py b/rl4co/envs/scheduling/fjsp/utils.py index b3ee40b8..f870e8b6 100644 --- a/rl4co/envs/scheduling/fjsp/utils.py +++ b/rl4co/envs/scheduling/fjsp/utils.py @@ -152,8 +152,8 @@ def first_diff(x: Tensor, dim: int): shape = x.shape shape = (*shape[:dim], 1, *shape[dim + 1 :]) seq_cutoff = x.index_select(dim, torch.arange(x.size(dim) - 1, device=x.device)) - lagged_seq = x - torch.cat((seq_cutoff.new_zeros(*shape), seq_cutoff), dim=dim) - return lagged_seq + first_diff_seq = x - torch.cat((seq_cutoff.new_zeros(*shape), seq_cutoff), dim=dim) + return first_diff_seq def spatial_encoding(td: TensorDict): @@ -205,7 +205,7 @@ def calc_lower_bound(td: TensorDict): We detect this offset by detecting ops-machine pairs, where the first possible start point of the operation is before the machine becomes idle again - Therefore, we add this discrepancy to the proc_time of the respective ops-ma combination - 2.) If an operation has been scheduled, we use its real finishing time as lower bound. In this case, using the cumulative sum + 2.) If an operation has been scheduled, we use its actual finishing time as lower bound. In this case, using the cumulative sum of all peedecessors of a job does not make sense, since it is likely to differ from the real finishing time of its direct predecessor (its only a lower bound). Therefore, we add the finish time to the cumulative sum of processing time of all UNSCHEDULED operations, to obtain the lower bound. @@ -213,8 +213,6 @@ def calc_lower_bound(td: TensorDict): add them to the matrix of processing times, where already processed operations are masked (with zero) - :param TensorDict td: _description_ - :return _type_: _description_ """ proc_times = td["proc_times"].clone() # (bs, ma, ops) @@ -231,12 +229,15 @@ def calc_lower_bound(td: TensorDict): maybe_start_at = torch.bmm(ops_adj[..., 0], finish_times[..., None]).squeeze(2) # using the start_time, we can determine if and how long an op needs to wait for a machine to finish wait_for_ma_offset = torch.clip(busy_until[..., None] - maybe_start_at[:, None], 0) - # we add this required waiting time to the respective processing time - after that we determine the best machine for each operation - mask = proc_times == 0 - proc_times[mask] = torch.inf - proc_times += wait_for_ma_offset - # select best machine for operation, given the offset - min_proc_times = proc_times.min(1).values + # we add this required waiting time to the respective processing time + proc_time_plus_wait = torch.where( + proc_times == 0, proc_times, proc_times + wait_for_ma_offset + ) + # NOTE get the mean processing time over all eligible machines for lb calulation + # ops_proc_times = torch.where(proc_times == 0, torch.inf, proc_time_plus_wait).min(1).values) + ops_proc_times = proc_time_plus_wait.sum(1) / (proc_times.gt(0).sum(1) + 1e-9) + # mask proc times for already scheduled ops + ops_proc_times[op_scheduled.to(torch.bool)] = 0 ############### REGARDING POINT 2 OF DOCSTRING ################### # Now we determine all operations that are not scheduled yet (and thus have no finish_time). We will compute the cumulative @@ -257,7 +258,7 @@ def calc_lower_bound(td: TensorDict): # masking the processing time of scheduled operations and add their finish times instead (first diff thereof) lb_end_expand = ( - proc_matrix_not_scheduled * min_proc_times.unsqueeze(1).expand_as(job_ops_adj) + proc_matrix_not_scheduled * ops_proc_times.unsqueeze(1).expand_as(job_ops_adj) + finish_times_1st_diff ) # (bs, max_ops); lower bound finish time per operation using the cumsum logic diff --git a/rl4co/envs/scheduling/jssp/env.py b/rl4co/envs/scheduling/jssp/env.py new file mode 100644 index 00000000..702ceda7 --- /dev/null +++ b/rl4co/envs/scheduling/jssp/env.py @@ -0,0 +1,123 @@ +import torch + +from einops import einsum, reduce +from tensordict import TensorDict +from torch._tensor import Tensor + +from rl4co.envs import FJSPEnv +from rl4co.utils.ops import gather_by_index + +from .generator import JSSPFileGenerator, JSSPGenerator + + +class JSSPEnv(FJSPEnv): + """Job-Shop Scheduling Problem (JSSP) environment + At each step, the agent chooses a job. The operation to be processed next for the selected job is + then executed on the associated machine. The reward is 0 unless the agent scheduled all operations of all jobs. + In that case, the reward is (-)makespan of the schedule: maximizing the reward is equivalent to minimizing the makespan. + NOTE: The JSSP is a special case of the FJSP, when the number of eligible machines per operation is equal to one for all + operations. Therefore, this environment is a subclass of the FJSP environment. + Observations: + - time: current time + - next_op: next operation per job + - proc_times: processing time of operation-machine pairs + - pad_mask: specifies padded operations + - start_op_per_job: id of first operation per job + - end_op_per_job: id of last operation per job + - start_times: start time of operation (defaults to 0 if not scheduled) + - finish_times: finish time of operation (defaults to INIT_FINISH if not scheduled) + - job_ops_adj: adjacency matrix specifying job-operation affiliation + - ops_job_map: same as above but using ids of jobs to indicate affiliation + - ops_sequence_order: specifies the order in which operations have to be processed + - ma_assignment: specifies which operation has been scheduled on which machine + - busy_until: specifies until when the machine will be busy + - num_eligible: number of machines that can process an operation + - job_in_process: whether job is currently being processed + - job_done: whether the job is done + + Constrains: + the agent may not select: + - jobs that are done already + - jobs that are currently processed + + Finish condition: + - the agent has scheduled all operations of all jobs + + Reward: + - the negative makespan of the final schedule + + Args: + generator: JSSPGenerator instance as the data generator + generator_params: parameters for the generator + mask_no_ops: if True, agent may not select waiting operation (unless instance is done) + """ + + name = "jssp" + + def __init__( + self, + generator: JSSPGenerator = None, + generator_params: dict = {}, + mask_no_ops: bool = True, + **kwargs, + ): + if generator is None: + if generator_params.get("file_path", None) is not None: + generator = JSSPFileGenerator(**generator_params) + else: + generator = JSSPGenerator(**generator_params) + + super().__init__(generator, generator_params, mask_no_ops, **kwargs) + + def _get_features(self, td): + td = super()._get_features(td) + # get the id of the machine that executes an operation: + # (bs, ops, ma) + ops_ma_adj = td["ops_ma_adj"].transpose(1, 2) + # (bs, jobs, ma) + ma_of_next_op = gather_by_index(ops_ma_adj, td["next_op"], dim=1) + # (bs, jobs) + td["next_ma"] = ma_of_next_op.argmax(-1) + + # adjacency matrix specifying neighbors of an operation, including its + # predecessor and successor operations and operations on the same machine + ops_on_same_ma_adj = einsum( + td["ops_ma_adj"], td["ops_ma_adj"], "b m o1, b m o2 -> b o1 o2 " + ) + # concat pred, succ and ops on same machine + adj = torch.cat((td["ops_adj"], ops_on_same_ma_adj.unsqueeze(-1)), dim=-1).sum(-1) + # mask padded operations and those scheduled + mask = td["pad_mask"] + td["op_scheduled"] + adj.masked_fill_(mask.unsqueeze(1), 0) + td["adjacency"] = adj + + return td + + def get_action_mask(self, td: TensorDict) -> Tensor: + action_mask = self._get_job_machine_availability(td) + if self.mask_no_ops: + # masking is only allowed if instance is finished + no_op_mask = td["done"] + else: + # if no job is currently processed and instance is not finished yet, waiting is not allowed + no_op_mask = ( + td["job_in_process"].any(1, keepdims=True) & (~td["done"]) + ) | td["done"] + # reduce action mask to correspond with logit shape + action_mask = reduce(action_mask, "bs j m -> bs j", reduction="all") + # NOTE: 1 means feasible action, 0 means infeasible action + # (bs, 1 + n_j) + mask = torch.cat((no_op_mask, ~action_mask), dim=1) + return mask + + def _translate_action(self, td): + job = td["action"] + op = gather_by_index(td["next_op"], job, dim=1) + # get the machine that corresponds to the selected operation + ma = gather_by_index(td["ops_ma_adj"], op.unsqueeze(1), dim=2).nonzero()[:, 1] + return job, op, ma + + @staticmethod + def load_data(fpath, batch_size=[]): + g = JSSPFileGenerator(fpath) + return g(batch_size=batch_size) diff --git a/rl4co/envs/scheduling/jssp/generator.py b/rl4co/envs/scheduling/jssp/generator.py new file mode 100644 index 00000000..bc9f1fc6 --- /dev/null +++ b/rl4co/envs/scheduling/jssp/generator.py @@ -0,0 +1,208 @@ +import os + +from functools import partial +from typing import List + +import numpy as np +import torch + +from tensordict.tensordict import TensorDict +from torch.nn.functional import one_hot + +from rl4co.envs.common.utils import Generator +from rl4co.utils.pylogger import get_pylogger + +from .parser import get_max_ops_from_files, read + +log = get_pylogger(__name__) + + +class JSSPGenerator(Generator): + + """Data generator for the Job-Shop Scheduling Problem (JSSP) + + Args: + num_stage: number of stages + num_machine: number of machines + num_job: number of jobs + min_time: minimum running time of each job on each machine + max_time: maximum running time of each job on each machine + flatten_stages: whether to flatten the stages + one2one_ma_map: whether each machine should have exactly one operation per job (common in jssp benchmark instances) + + Returns: + A TensorDict with the following key: + start_op_per_job [batch_size, num_jobs]: first operation of each job + end_op_per_job [batch_size, num_jobs]: last operation of each job + proc_times [batch_size, num_machines, total_n_ops]: processing time of ops on machines + pad_mask [batch_size, total_n_ops]: not all instances have the same number of ops, so padding is used + + """ + + def __init__( + self, + num_jobs: int = 6, + num_machines: int = 6, + min_ops_per_job: int = None, + max_ops_per_job: int = None, + min_processing_time: int = 1, + max_processing_time: int = 99, + one2one_ma_map: bool = True, + **unused_kwargs, + ): + self.num_jobs = num_jobs + self.num_mas = num_machines + # quite common in jssp to have as many ops per job as there are machines + self.min_ops_per_job = min_ops_per_job or self.num_mas + self.max_ops_per_job = max_ops_per_job or self.num_mas + self.min_processing_time = min_processing_time + self.max_processing_time = max_processing_time + self.one2one_ma_map = one2one_ma_map + if self.one2one_ma_map: + assert self.min_ops_per_job == self.max_ops_per_job == self.num_mas + + # determines whether to use a fixed number of total operations or let it vary between instances + # NOTE: due to the way rl4co builds datasets, we need a fixed size here + self.n_ops_max = self.max_ops_per_job * self.num_jobs + + # FFSP environment doen't have any other kwargs + if len(unused_kwargs) > 0: + log.error(f"Found {len(unused_kwargs)} unused kwargs: {unused_kwargs}") + + def _simulate_processing_times(self, bs, n_ops_max) -> torch.Tensor: + if self.one2one_ma_map: + ops_machine_ids = ( + torch.rand((*bs, self.num_jobs, self.num_mas)) + .argsort(dim=-1) + .flatten(1, 2) + ) + else: + ops_machine_ids = torch.randint( + low=0, + high=self.num_mas, + size=(*bs, n_ops_max), + ) + ops_machine_adj = one_hot(ops_machine_ids, num_classes=self.num_mas) + + # (bs, max_ops, machines) + proc_times = torch.ones((*bs, n_ops_max, self.num_mas)) + proc_times = torch.randint( + self.min_processing_time, + self.max_processing_time + 1, + size=(*bs, self.num_mas, n_ops_max), + ) + + # remove proc_times for which there is no corresponding ma-ops connection + proc_times = proc_times * ops_machine_adj.transpose(1, 2) + # in JSSP there is only one machine capable to process an operation + assert (proc_times > 0).sum(1).eq(1).all() + return proc_times.to(torch.float32) + + def _generate(self, batch_size) -> TensorDict: + # simulate how many operations each job has + n_ope_per_job = torch.randint( + self.min_ops_per_job, + self.max_ops_per_job + 1, + size=(*batch_size, self.num_jobs), + ) + + # determine the total number of operations per batch instance (which may differ) + n_ops_batch = n_ope_per_job.sum(1) # (bs) + # determine the maximum total number of operations over all batch instances + n_ops_max = self.n_ops_max or n_ops_batch.max() + + # generate a mask, specifying which operations are padded + pad_mask = torch.arange(n_ops_max).unsqueeze(0).expand(*batch_size, -1) + pad_mask = pad_mask.ge(n_ops_batch[:, None].expand_as(pad_mask)) + + # determine the id of the end operation for each job + end_op_per_job = n_ope_per_job.cumsum(1) - 1 + + # determine the id of the starting operation for each job + # (bs, num_jobs) + start_op_per_job = torch.cat( + ( + torch.zeros((*batch_size, 1)).to(end_op_per_job), + end_op_per_job[:, :-1] + 1, + ), + dim=1, + ) + + # simulate processing times for machine-operation pairs + # (bs, num_mas, n_ops_max) + proc_times = self._simulate_processing_times(batch_size, n_ops_max) + + td = TensorDict( + { + "start_op_per_job": start_op_per_job, + "end_op_per_job": end_op_per_job, + "proc_times": proc_times, + "pad_mask": pad_mask, + }, + batch_size=batch_size, + ) + + return td + + +class JSSPFileGenerator(Generator): + """Data generator for the Job-Shop Scheduling Problem (JSSP) using instance files + + Args: + path: path to files + + Returns: + A TensorDict with the following key: + start_op_per_job [batch_size, num_jobs]: first operation of each job + end_op_per_job [batch_size, num_jobs]: last operation of each job + proc_times [batch_size, num_machines, total_n_ops]: processing time of ops on machines + pad_mask [batch_size, total_n_ops]: not all instances have the same number of ops, so padding is used + + """ + + def __init__(self, file_path: str, n_ops_max: int = None, **unused_kwargs): + self.files = ( + [file_path] if os.path.isfile(file_path) else self.list_files(file_path) + ) + self.num_samples = len(self.files) + + if len(unused_kwargs) > 0: + log.error(f"Found {len(unused_kwargs)} unused kwargs: {unused_kwargs}") + + if len(self.files) > 1: + n_ops_max = get_max_ops_from_files(self.files) + + ret = map(partial(read, max_ops=n_ops_max), self.files) + + td_list, num_jobs, num_machines, max_ops_per_job = list(zip(*list(ret))) + num_jobs, num_machines = map(lambda x: x[0], (num_jobs, num_machines)) + max_ops_per_job = max(max_ops_per_job) + + self.td = torch.cat(td_list, dim=0) + self.num_mas = num_machines + self.num_jobs = num_jobs + self.max_ops_per_job = max_ops_per_job + self.start_idx = 0 + + def _generate(self, batch_size: List[int]) -> TensorDict: + batch_size = np.prod(batch_size) + if batch_size > self.num_samples: + log.warning( + f"Only found {self.num_samples} instance files, but specified dataset size is {batch_size}" + ) + end_idx = self.start_idx + batch_size + td = self.td[self.start_idx : end_idx] + self.start_idx += batch_size + if self.start_idx >= self.num_samples: + self.start_idx = 0 + return td + + @staticmethod + def list_files(path): + files = [ + os.path.join(path, f) + for f in os.listdir(path) + if os.path.isfile(os.path.join(path, f)) + ] + assert len(files) > 0, "No files found in the specified path" + return files diff --git a/rl4co/envs/scheduling/jssp/parser.py b/rl4co/envs/scheduling/jssp/parser.py new file mode 100644 index 00000000..9fcdb4bf --- /dev/null +++ b/rl4co/envs/scheduling/jssp/parser.py @@ -0,0 +1,110 @@ +from pathlib import Path +from typing import List, Tuple, Union + +import torch + +from tensordict import TensorDict + +ProcessingData = List[Tuple[int, int]] + + +def parse_job_line(line: Tuple[int]) -> Tuple[ProcessingData]: + """ + Parses a JSSP job data line of the following form: + + * ( ) + + In words, a line consist of n_ops pairs of values, where the first value is the + machine identifier and the second value is the processing time of the corresponding + operation-machine combination + + Note that the machine indices start from 1, so we subtract 1 to make them + zero-based. + """ + + operations = [] + i = 0 + + while i < len(line): + machine = int(line[i]) + duration = int(line[i + 1]) + operations.append((machine, duration)) + i += 2 + + return operations + + +def get_n_ops_of_instance(file): + lines = file2lines(file) + jobs = [parse_job_line(line) for line in lines[1:]] + n_ope_per_job = torch.Tensor([len(x) for x in jobs]).unsqueeze(0) + total_ops = int(n_ope_per_job.sum()) + return total_ops + + +def get_max_ops_from_files(files): + return max(map(get_n_ops_of_instance, files)) + + +def read(loc: Path, max_ops=None): + """ + Reads an JSSP instance. + + Args: + loc: location of instance file + max_ops: optionally specify the maximum number of total operations (will be filled by padding) + + Returns: + instance: the parsed instance + """ + lines = file2lines(loc) + + # First line contains metadata. + num_jobs, num_machines = lines[0][0], lines[0][1] + + # The remaining lines contain the job-operation data, where each line + # represents a job and its operations. + jobs = [parse_job_line(line) for line in lines[1:]] + n_ope_per_job = torch.Tensor([len(x) for x in jobs]).unsqueeze(0) + total_ops = int(n_ope_per_job.sum()) + if max_ops is not None: + assert total_ops <= max_ops, "got more operations then specified through max_ops" + max_ops = max_ops or total_ops + max_ops_per_job = int(n_ope_per_job.max()) + + end_op_per_job = n_ope_per_job.cumsum(1) - 1 + start_op_per_job = torch.cat((torch.zeros((1, 1)), end_op_per_job[:, :-1] + 1), dim=1) + + pad_mask = torch.arange(max_ops) + pad_mask = pad_mask.ge(total_ops).unsqueeze(0) + + proc_times = torch.zeros((num_machines, max_ops)) + op_cnt = 0 + for job in jobs: + for ma, dur in job: + # subtract one to let indices start from zero + proc_times[ma - 1, op_cnt] = dur + op_cnt += 1 + proc_times = proc_times.unsqueeze(0) + + td = TensorDict( + { + "start_op_per_job": start_op_per_job, + "end_op_per_job": end_op_per_job, + "proc_times": proc_times, + "pad_mask": pad_mask, + }, + batch_size=[1], + ) + + return td, num_jobs, num_machines, max_ops_per_job + + +def file2lines(loc: Union[Path, str]) -> List[List[int]]: + with open(loc, "r") as fh: + lines = [line for line in fh.readlines() if line.strip()] + + def parse_num(word: str): + return int(word) if "." not in word else int(float(word)) + + return [[parse_num(x) for x in line.split()] for line in lines] diff --git a/rl4co/models/__init__.py b/rl4co/models/__init__.py index 5b81cd3e..9ee741e4 100644 --- a/rl4co/models/__init__.py +++ b/rl4co/models/__init__.py @@ -14,12 +14,12 @@ NonAutoregressivePolicy, ) from rl4co.models.common.transductive import TransductiveModel +from rl4co.models.rl import StepwisePPO from rl4co.models.rl.a2c.a2c import A2C from rl4co.models.rl.common.base import RL4COLitModule from rl4co.models.rl.ppo.ppo import PPO from rl4co.models.rl.reinforce.baselines import REINFORCEBaseline, get_reinforce_baseline from rl4co.models.rl.reinforce.reinforce import REINFORCE -from rl4co.models.zoo import HetGNNModel from rl4co.models.zoo.active_search import ActiveSearch from rl4co.models.zoo.am import AttentionModel, AttentionModelPolicy from rl4co.models.zoo.amppo import AMPPO @@ -29,12 +29,19 @@ HeterogeneousAttentionModel, HeterogeneousAttentionModelPolicy, ) +from rl4co.models.zoo.l2d import ( + L2DAttnPolicy, + L2DModel, + L2DPolicy, + L2DPolicy4PPO, + L2DPPOModel, +) from rl4co.models.zoo.matnet import MatNet, MatNetPolicy from rl4co.models.zoo.mdam import MDAM, MDAMPolicy +from rl4co.models.zoo.mvmoe import MVMoE_AM, MVMoE_POMO from rl4co.models.zoo.n2s import N2S, N2SPolicy from rl4co.models.zoo.nargnn import NARGNNPolicy from rl4co.models.zoo.polynet import PolyNet from rl4co.models.zoo.pomo import POMO from rl4co.models.zoo.ptrnet import PointerNetwork, PointerNetworkPolicy from rl4co.models.zoo.symnco import SymNCO, SymNCOPolicy -from rl4co.models.zoo.mvmoe import MVMoE_POMO, MVMoE_AM diff --git a/rl4co/models/nn/attention.py b/rl4co/models/nn/attention.py index 6e4330b0..f7742103 100644 --- a/rl4co/models/nn/attention.py +++ b/rl4co/models/nn/attention.py @@ -2,7 +2,7 @@ import math import warnings -from typing import Callable, Optional +from typing import Callable, Optional, Union import torch import torch.nn as nn @@ -108,21 +108,113 @@ def __init__( self.Wqkv = nn.Linear(embed_dim, 3 * embed_dim, bias=bias, **factory_kwargs) self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias, **factory_kwargs) - def forward(self, x, key_padding_mask=None): + def forward(self, x, attn_mask=None): """x: (batch, seqlen, hidden_dim) (where hidden_dim = num heads * head dim) - key_padding_mask: bool tensor of shape (batch, seqlen) + attn_mask: bool tensor of shape (batch, seqlen) """ # Project query, key, value q, k, v = rearrange( self.Wqkv(x), "b s (three h d) -> three b h s d", three=3, h=self.num_heads ).unbind(dim=0) + if attn_mask is not None: + attn_mask = ( + attn_mask.unsqueeze(1) + if attn_mask.ndim == 3 + else attn_mask.unsqueeze(1).unsqueeze(2) + ) + # Scaled dot product attention out = self.sdpa_fn( q, k, v, - attn_mask=key_padding_mask, + attn_mask=attn_mask, + dropout_p=self.attention_dropout, + ) + return self.out_proj(rearrange(out, "b h s d -> b s (h d)")) + + +def sdpa_fn_wrapper(q, k, v, attn_mask=None, dmat=None, dropout_p=0.0, is_causal=False): + if dmat is not None: + log.warning( + "Edge weights passed to simple attention-fn, which is not supported. Weights will be ignored..." + ) + return scaled_dot_product_attention( + q, k, v, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal + ) + + +class MultiHeadCrossAttention(nn.Module): + """PyTorch native implementation of Flash Multi-Head Cross Attention with automatic mixed precision support. + Uses PyTorch's native `scaled_dot_product_attention` implementation, available from 2.0 + + Note: + If `scaled_dot_product_attention` is not available, use custom implementation of `scaled_dot_product_attention` without Flash Attention. + + Args: + embed_dim: total dimension of the model + num_heads: number of heads + bias: whether to use bias + attention_dropout: dropout rate for attention weights + device: torch device + dtype: torch dtype + sdpa_fn: scaled dot product attention function (SDPA) + """ + + def __init__( + self, + embed_dim: int, + num_heads: int, + bias: bool = False, + attention_dropout: float = 0.0, + device: str = None, + dtype: torch.dtype = None, + sdpa_fn: Optional[Union[Callable, nn.Module]] = None, + ) -> None: + factory_kwargs = {"device": device, "dtype": dtype} + super().__init__() + self.embed_dim = embed_dim + self.attention_dropout = attention_dropout + + # Default to `scaled_dot_product_attention` if `sdpa_fn` is not provided + if sdpa_fn is None: + sdpa_fn = sdpa_fn_wrapper + self.sdpa_fn = sdpa_fn + + self.num_heads = num_heads + assert self.embed_dim % num_heads == 0, "self.kdim must be divisible by num_heads" + self.head_dim = self.embed_dim // num_heads + assert ( + self.head_dim % 8 == 0 and self.head_dim <= 128 + ), "Only support head_dim <= 128 and divisible by 8" + + self.Wq = nn.Linear(embed_dim, embed_dim, bias=bias, **factory_kwargs) + self.Wkv = nn.Linear(embed_dim, 2 * embed_dim, bias=bias, **factory_kwargs) + self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias, **factory_kwargs) + + def forward(self, q_input, kv_input, cross_attn_mask=None, dmat=None): + # Project query, key, value + q = rearrange( + self.Wq(q_input), "b m (h d) -> b h m d", h=self.num_heads + ) # [b, h, m, d] + k, v = rearrange( + self.Wkv(kv_input), "b n (two h d) -> two b h n d", two=2, h=self.num_heads + ).unbind( + dim=0 + ) # [b, h, n, d] + + if cross_attn_mask is not None: + # add head dim + cross_attn_mask = cross_attn_mask.unsqueeze(1) + + # Scaled dot product attention + out = self.sdpa_fn( + q, + k, + v, + attn_mask=cross_attn_mask, + dmat=dmat, dropout_p=self.attention_dropout, ) return self.out_proj(rearrange(out, "b h s d -> b s (h d)")) @@ -250,11 +342,15 @@ def __init__( sdpa_fn: Optional[Callable] = None, moe_kwargs: Optional[dict] = None, ): - super(PointerAttnMoE, self).__init__(embed_dim, num_heads, mask_inner, out_bias, check_nan, sdpa_fn) + super(PointerAttnMoE, self).__init__( + embed_dim, num_heads, mask_inner, out_bias, check_nan, sdpa_fn + ) self.moe_kwargs = moe_kwargs self.project_out = None - self.project_out_moe = MoE(embed_dim, embed_dim, num_neurons=[], out_bias=out_bias, **moe_kwargs) + self.project_out_moe = MoE( + embed_dim, embed_dim, num_neurons=[], out_bias=out_bias, **moe_kwargs + ) if self.moe_kwargs["light_version"]: self.dense_or_moe = nn.Linear(embed_dim, 2, bias=False) self.project_out = nn.Linear(embed_dim, embed_dim, bias=out_bias) @@ -262,9 +358,16 @@ def __init__( def _project_out(self, out): """Implementation of Hierarchical Gating based on Zhou et al. (2024) .""" if self.moe_kwargs["light_version"]: - probs = F.softmax(self.dense_or_moe(out.view(-1, out.size(-1)).mean(dim=0, keepdim=True)), dim=-1) + probs = F.softmax( + self.dense_or_moe(out.view(-1, out.size(-1)).mean(dim=0, keepdim=True)), + dim=-1, + ) selected = probs.multinomial(1).squeeze(0) - out = self.project_out_moe(out) if selected.item() == 1 else self.project_out(out) + out = ( + self.project_out_moe(out) + if selected.item() == 1 + else self.project_out(out) + ) glimpse = out * probs.squeeze(0)[selected] else: glimpse = self.project_out_moe(out) diff --git a/rl4co/models/nn/env_embeddings/context.py b/rl4co/models/nn/env_embeddings/context.py index 8c651663..1fd63db8 100644 --- a/rl4co/models/nn/env_embeddings/context.py +++ b/rl4co/models/nn/env_embeddings/context.py @@ -321,6 +321,19 @@ def forward(self, embeddings, td): return self.project_context(cur_node_embedding) +class SchedulingContext(nn.Module): + def __init__(self, embed_dim: int, scaling_factor: int = 1000): + super().__init__() + self.scaling_factor = scaling_factor + self.proj_busy = nn.Linear(1, embed_dim, bias=False) + + def forward(self, h, td): + busy_for = (td["busy_until"] - td["time"].unsqueeze(1)) / self.scaling_factor + busy_proj = self.proj_busy(busy_for.unsqueeze(-1)) + # (b m e) + return h + busy_proj + + class MTVRPContext(VRPContext): """Context embedding for Multi-Task VRPEnv. Project the following to the embedding space: @@ -338,10 +351,22 @@ def __init__(self, embed_dim): ) def _state_embedding(self, embeddings, td): - remaining_linehaul_capacity = td["vehicle_capacity"] - td["used_capacity_linehaul"] - remaining_backhaul_capacity = td["vehicle_capacity"] - td["used_capacity_backhaul"] + remaining_linehaul_capacity = ( + td["vehicle_capacity"] - td["used_capacity_linehaul"] + ) + remaining_backhaul_capacity = ( + td["vehicle_capacity"] - td["used_capacity_backhaul"] + ) current_time = td["current_time"] current_route_length = td["current_route_length"] open_route = td["open_route"] - return torch.cat([remaining_linehaul_capacity, remaining_backhaul_capacity, current_time, - current_route_length, open_route], -1) + return torch.cat( + [ + remaining_linehaul_capacity, + remaining_backhaul_capacity, + current_time, + current_route_length, + open_route, + ], + -1, + ) diff --git a/rl4co/models/nn/env_embeddings/dynamic.py b/rl4co/models/nn/env_embeddings/dynamic.py index 9d9db535..470af835 100644 --- a/rl4co/models/nn/env_embeddings/dynamic.py +++ b/rl4co/models/nn/env_embeddings/dynamic.py @@ -1,5 +1,7 @@ +import torch import torch.nn as nn +from rl4co.utils.ops import gather_by_index from rl4co.utils.pylogger import get_pylogger log = get_pylogger(__name__) @@ -30,6 +32,8 @@ def env_dynamic_embedding(env_name: str, config: dict) -> nn.Module: "pdp": StaticEmbedding, "mtsp": StaticEmbedding, "smtwtp": StaticEmbedding, + "jssp": JSSPDynamicEmbedding, + "fjsp": JSSPDynamicEmbedding, "mtvrp": StaticEmbedding, } @@ -72,3 +76,46 @@ def forward(self, td): demands_with_depot ).chunk(3, dim=-1) return glimpse_key_dynamic, glimpse_val_dynamic, logit_key_dynamic + + +class JSSPDynamicEmbedding(nn.Module): + def __init__(self, embed_dim, linear_bias=False, scaling_factor: int = 1000) -> None: + super().__init__() + self.embed_dim = embed_dim + self.project_node_step = nn.Linear(2, 3 * embed_dim, bias=linear_bias) + self.project_edge_step = nn.Linear(1, 3, bias=linear_bias) + self.scaling_factor = scaling_factor + + def forward(self, td, cache): + ma_emb = cache.node_embeddings["machine_embeddings"] + bs, _, emb_dim = ma_emb.shape + num_jobs = td["next_op"].size(1) + # updates + updates = ma_emb.new_zeros((bs, num_jobs, 3 * emb_dim)) + + lbs = torch.clip(td["lbs"] - td["time"][:, None], 0) / self.scaling_factor + update_feat = torch.stack((lbs, td["is_ready"]), dim=-1) + job_update_feat = gather_by_index(update_feat, td["next_op"], dim=1) + updates = updates + self.project_node_step(job_update_feat) + + ma_busy = td["busy_until"] > td["time"][:, None] + # mask machines currently busy + masked_proc_times = td["proc_times"].clone() / self.scaling_factor + # bs, ma, ops + masked_proc_times[ma_busy] = 0.0 + # bs, ops, ma, 3 + edge_feat = self.project_edge_step(masked_proc_times.unsqueeze(-1)).transpose( + 1, 2 + ) + job_edge_feat = gather_by_index(edge_feat, td["next_op"], dim=1) + # bs, nodes, 3*emb + edge_upd = torch.einsum("ijkl,ikm->ijlm", job_edge_feat, ma_emb).view( + bs, num_jobs, 3 * emb_dim + ) + updates = updates + edge_upd + + # (bs, nodes, emb) + glimpse_key_dynamic, glimpse_val_dynamic, logit_key_dynamic = updates.chunk( + 3, dim=-1 + ) + return glimpse_key_dynamic, glimpse_val_dynamic, logit_key_dynamic diff --git a/rl4co/models/nn/env_embeddings/init.py b/rl4co/models/nn/env_embeddings/init.py index 3b094b84..063c1550 100644 --- a/rl4co/models/nn/env_embeddings/init.py +++ b/rl4co/models/nn/env_embeddings/init.py @@ -33,7 +33,8 @@ def env_init_embedding(env_name: str, config: dict) -> nn.Module: "mtsp": MTSPInitEmbedding, "smtwtp": SMTWTPInitEmbedding, "mdcpdp": MDCPDPInitEmbedding, - "fjsp": FJSPFeatureEmbedding, + "fjsp": FJSPInitEmbedding, + "jssp": FJSPInitEmbedding, "mtvrp": MTVRPInitEmbedding, } @@ -63,7 +64,7 @@ def forward(self, td): class MatNetInitEmbedding(nn.Module): """ - Preparing the initial row and column embeddings for FFSP. + Preparing the initial row and column embeddings for MatNet. Reference: https://github.com/yd-kwon/MatNet/blob/782698b60979effe2e7b61283cca155b7cdb727f/ATSP/ATSP_MatNet/ATSPModel.py#L51 @@ -98,7 +99,7 @@ def forward(self, td: TensorDict): col_emb[b_idx, n_idx, rand_idx] = 1.0 elif self.mode == "Random": - col_emb = torch.rand(b, r, self.embed_dim, device=dmat.device) + col_emb = torch.rand(b, c, self.embed_dim, device=dmat.device) else: raise NotImplementedError @@ -386,66 +387,115 @@ def forward(self, td): return torch.cat([depot_embeddings, pick_embeddings, delivery_embeddings], -2) -class FJSPFeatureEmbedding(nn.Module): - def __init__(self, embed_dim, linear_bias=True, norm_coef: int = 100): - super().__init__() +class JSSPInitEmbedding(nn.Module): + def __init__( + self, + embed_dim, + linear_bias: bool = True, + scaling_factor: int = 1000, + num_op_feats=5, + ): + super(JSSPInitEmbedding, self).__init__() self.embed_dim = embed_dim - self.norm_coef = norm_coef + self.scaling_factor = scaling_factor + self.init_ops_embed = nn.Linear(num_op_feats, embed_dim, linear_bias) + self.pos_encoder = PositionalEncoding(embed_dim, dropout=0.0) + + def _op_features(self, td): + proc_times = td["proc_times"] + mean_durations = proc_times.sum(1) / (proc_times.gt(0).sum(1) + 1e-9) + feats = [ + mean_durations / self.scaling_factor, + td["is_ready"], + td["num_eligible"], + td["ops_job_map"], + td["op_scheduled"], + ] + return torch.stack(feats, dim=-1) - self.init_ope_embed = nn.Linear(4, self.embed_dim, bias=False) - self.edge_embed = nn.Linear(1, embed_dim, bias=False) + def _init_ops_embed(self, td: TensorDict): + ops_feat = self._op_features(td) + ops_emb = self.init_ops_embed(ops_feat) + ops_emb = self.pos_encoder(ops_emb, td["ops_sequence_order"]) - self.ope_pos_enc = PositionalEncoding(embed_dim) - # TODO allow for reencoding after each step - self.stepwise = False + # zero out padded and finished ops + mask = td["pad_mask"] # NOTE dont mask scheduled - leads to instable training + ops_emb[mask.unsqueeze(-1).expand_as(ops_emb)] = 0 + return ops_emb - def forward(self, td: TensorDict): - if self.stepwise: - ops_emb = self._stepwise_operations_embed(td) - ma_emb = self._stepwise_machine_embed(td) - edge_emb = None - else: - ops_emb = self._init_operations_embed(td) - ma_emb = self._init_machine_embed(td) - edge_emb = self._init_edge_embed(td) - return ma_emb, ops_emb, edge_emb - - def _init_operations_embed(self, td: TensorDict): - pos = td["ops_sequence_order"] - - features = [ - td["lbs"].unsqueeze(-1) / self.norm_coef, - td["is_ready"].unsqueeze(-1), - td["num_eligible"].unsqueeze(-1), - td["ops_job_map"].unsqueeze(-1), + def forward(self, td): + return self._init_ops_embed(td) + + +class FJSPInitEmbedding(JSSPInitEmbedding): + def __init__(self, embed_dim, linear_bias=False, scaling_factor: int = 100): + super().__init__(embed_dim, linear_bias, scaling_factor, num_op_feats=5) + self.init_ma_embed = nn.Linear(1, self.embed_dim, bias=linear_bias) + self.edge_embed = nn.Linear(1, embed_dim, bias=linear_bias) + + def _op_features(self, td): + feats = [ + td["lbs"] / self.scaling_factor, + td["is_ready"], + td["num_eligible"], + td["op_scheduled"], + td["ops_job_map"], ] - features = torch.cat(features, dim=-1) - # (bs, num_ops, emb_dim) - ops_embeddings = self.init_ope_embed(features) + return torch.stack(feats, dim=-1) - # (bs, num_ops, emb_dim) - ops_embeddings = self.ope_pos_enc(ops_embeddings, pos.to(torch.int64)) - # zero out padded entries - ops_embeddings[td["pad_mask"].unsqueeze(-1).expand_as(ops_embeddings)] = 0 - return ops_embeddings + def forward(self, td: TensorDict): + ops_emb = self._init_ops_embed(td) + ma_emb = self._init_machine_embed(td) + edge_emb = self._init_edge_embed(td) + # get edges between operations and machines + # (bs, ops, ma) + edges = td["ops_ma_adj"].transpose(1, 2) + return ops_emb, ma_emb, edge_emb, edges + + def _init_edge_embed(self, td: TensorDict): + proc_times = td["proc_times"].transpose(1, 2) / self.scaling_factor + edge_embed = self.edge_embed(proc_times.unsqueeze(-1)) + return edge_embed def _init_machine_embed(self, td: TensorDict): - bs, num_ma = td["busy_until"].shape - ma_embeddings = torch.zeros( - (bs, num_ma, self.embed_dim), device=td.device, dtype=torch.float32 - ) + busy_for = (td["busy_until"] - td["time"].unsqueeze(1)) / self.scaling_factor + ma_embeddings = self.init_ma_embed(busy_for.unsqueeze(2)) return ma_embeddings - def _init_edge_embed(self, td: TensorDict): - proc_times = td["proc_times"].unsqueeze(-1) / self.norm_coef - edge_embed = self.edge_embed(proc_times) - return edge_embed - def _stepwise_operations_embed(self, td: TensorDict): - raise NotImplementedError("Stepwise encoding not yet implemented") +class FJSPMatNetInitEmbedding(JSSPInitEmbedding): + def __init__( + self, + embed_dim, + linear_bias: bool = False, + scaling_factor: int = 1000, + ): + super().__init__(embed_dim, linear_bias, scaling_factor, num_op_feats=5) + self.init_ma_embed = nn.Linear(1, self.embed_dim, bias=linear_bias) + + def _op_features(self, td): + feats = [ + td["lbs"] / self.scaling_factor, + td["is_ready"], + td["op_scheduled"], + td["num_eligible"], + td["ops_job_map"], + ] + return torch.stack(feats, dim=-1) + + def _init_machine_embed(self, td: TensorDict): + busy_for = (td["busy_until"] - td["time"].unsqueeze(1)) / self.scaling_factor + ma_embeddings = self.init_ma_embed(busy_for.unsqueeze(2)) + return ma_embeddings - def _stepwise_machine_embed(self, td: TensorDict): - raise NotImplementedError("Stepwise encoding not yet implemented") + def forward(self, td: TensorDict): + proc_times = td["proc_times"] + ops_emb = self._init_ops_embed(td) + # encoding machines + ma_emb = self._init_machine_embed(td) + # edgeweights for matnet + matnet_edge_weights = proc_times.transpose(1, 2) / self.scaling_factor + return ops_emb, ma_emb, matnet_edge_weights class MTVRPInitEmbedding(VRPInitEmbedding): @@ -455,16 +505,26 @@ def __init__(self, embed_dim, linear_bias=True, node_dim: int = 7): def forward(self, td): depot, cities = td["locs"][:, :1, :], td["locs"][:, 1:, :] - demand_linehaul, demand_backhaul = td["demand_linehaul"][..., 1:], td["demand_backhaul"][..., 1:] + demand_linehaul, demand_backhaul = ( + td["demand_linehaul"][..., 1:], + td["demand_backhaul"][..., 1:], + ) service_time = td["service_time"][..., 1:] time_windows = td["time_windows"][..., 1:, :] # [!] convert [0, inf] -> [0, 0] if a problem does not include the time window constraint, do not modify in-place - time_windows = torch.nan_to_num(time_windows, posinf=0.0) + time_windows = torch.nan_to_num(time_windows, posinf=0.0) # embeddings depot_embedding = self.init_embed_depot(depot) node_embeddings = self.init_embed( torch.cat( - (cities, demand_linehaul[..., None], demand_backhaul[..., None], time_windows, service_time[..., None]), -1 + ( + cities, + demand_linehaul[..., None], + demand_backhaul[..., None], + time_windows, + service_time[..., None], + ), + -1, ) ) return torch.cat((depot_embedding, node_embeddings), -2) diff --git a/rl4co/models/nn/graph/gcn.py b/rl4co/models/nn/graph/gcn.py index 5f0ba34e..348c6b21 100644 --- a/rl4co/models/nn/graph/gcn.py +++ b/rl4co/models/nn/graph/gcn.py @@ -1,13 +1,15 @@ -from typing import Tuple, Union +from typing import Callable, Tuple, Union import torch.nn as nn import torch.nn.functional as F from tensordict import TensorDict from torch import Tensor -from torch_geometric.data import Batch, Data -from torch_geometric.nn import GCNConv +try: + from torch_geometric.nn import GCNConv +except ImportError: + GCNConv = None from rl4co.models.nn.env_embeddings import env_init_embedding from rl4co.utils.ops import get_full_graph_edge_index from rl4co.utils.pylogger import get_pylogger @@ -15,8 +17,17 @@ log = get_pylogger(__name__) +EdgeIndexFnSignature = Callable[[TensorDict, int], Tensor] + + +def edge_idx_fn_wrapper(td: TensorDict, num_nodes: int): + # self-loop is added by GCNConv layer + return get_full_graph_edge_index(num_nodes, self_loop=False).to(td.device) + + class GCNEncoder(nn.Module): - """Graph Convolutional Network to encode embeddings with a series of GCN layers + """Graph Convolutional Network to encode embeddings with a series of GCN + layers from the pytorch geometric package Args: embed_dim: dimension of the embeddings @@ -30,15 +41,19 @@ def __init__( self, env_name: str, embed_dim: int, - num_nodes: int, num_layers: int, init_embedding: nn.Module = None, - self_loop: bool = False, residual: bool = True, + edge_idx_fn: EdgeIndexFnSignature = None, + dropout: float = 0.5, + bias: bool = True, ): - super(GCNEncoder, self).__init__() + super().__init__() self.env_name = env_name + self.embed_dim = embed_dim + self.residual = residual + self.dropout = dropout self.init_embedding = ( env_init_embedding(self.env_name, {"embed_dim": embed_dim}) @@ -46,19 +61,17 @@ def __init__( else init_embedding ) - # Generate edge index for a fully connected graph - self.edge_index = get_full_graph_edge_index(num_nodes, self_loop) + if edge_idx_fn is None: + log.warning("No edge indices passed. Assume a fully connected graph") + edge_idx_fn = edge_idx_fn_wrapper + + self.edge_idx_fn = edge_idx_fn # Define the GCN layers self.gcn_layers = nn.ModuleList( - [GCNConv(embed_dim, embed_dim) for _ in range(num_layers)] + [GCNConv(embed_dim, embed_dim, bias=bias) for _ in range(num_layers)] ) - # Record parameters - self.residual = residual - self.self_loop = self_loop - - # def forward(self, x, node_feature, mask=None): def forward( self, td: TensorDict, mask: Union[Tensor, None] = None ) -> Tuple[Tensor, Tensor]: @@ -75,35 +88,27 @@ def forward( """ # Transfer to embedding space init_h = self.init_embedding(td) - num_node = init_h.size(-2) - - # Check to update the edge index with different number of node - if num_node != self.edge_index.max().item() + 1: - edge_index = get_full_graph_edge_index(num_node, self.self_loop).to( - init_h.device - ) - else: - edge_index = self.edge_index.to(init_h.device) - - # Create the batched graph - data_list = [Data(x=x, edge_index=edge_index) for x in init_h] - data_batch = Batch.from_data_list(data_list) + bs, num_nodes, emb_dim = init_h.shape + # (bs*num_nodes, emb_dim) + update_node_feature = init_h.reshape(-1, emb_dim) + # shape=(2, num_edges) + edge_index = self.edge_idx_fn(td, num_nodes) - # GCN process - update_node_feature = data_batch.x - edge_index = data_batch.edge_index for layer in self.gcn_layers[:-1]: update_node_feature = layer(update_node_feature, edge_index) update_node_feature = F.relu(update_node_feature) - update_node_feature = F.dropout(update_node_feature, training=self.training) + update_node_feature = F.dropout( + update_node_feature, training=self.training, p=self.dropout + ) + # last layer without relu activation and dropout update_node_feature = self.gcn_layers[-1](update_node_feature, edge_index) # De-batch the graph - input_size = init_h.size() - update_node_feature = update_node_feature.view(*input_size) + update_node_feature = update_node_feature.view(bs, num_nodes, emb_dim) # Residual - update_node_feature = update_node_feature + init_h + if self.residual: + update_node_feature = update_node_feature + init_h return update_node_feature, init_h diff --git a/rl4co/models/zoo/hetgnn/encoder.py b/rl4co/models/nn/graph/hgnn.py similarity index 80% rename from rl4co/models/zoo/hetgnn/encoder.py rename to rl4co/models/nn/graph/hgnn.py index 6f966cf8..bd4ce0d2 100644 --- a/rl4co/models/zoo/hetgnn/encoder.py +++ b/rl4co/models/nn/graph/hgnn.py @@ -8,7 +8,7 @@ from torch import Tensor from rl4co.models.nn.env_embeddings import env_init_embedding -from rl4co.models.nn.ops import Normalization +from rl4co.models.nn.ops import TransformerFFN class HetGNNLayer(nn.Module): @@ -75,24 +75,24 @@ def forward( cross_emb = einsum(cross_attn_scores, other_emb_aug, "b m o, b m o e -> b m e") self_emb = self_emb * self_attn_scores # (bs, n_ma, emb_dim) - hidden = torch.sigmoid(cross_emb + self_emb) + hidden = cross_emb + self_emb return hidden class HetGNNBlock(nn.Module): - def __init__(self, embed_dim) -> None: + def __init__(self, embed_dim, normalization: str = "batch") -> None: super().__init__() - self.norm1 = Normalization(embed_dim, normalization="batch") - self.norm2 = Normalization(embed_dim, normalization="batch") self.hgnn1 = HetGNNLayer(embed_dim) self.hgnn2 = HetGNNLayer(embed_dim) + self.ffn1 = TransformerFFN(embed_dim, embed_dim * 2, normalization=normalization) + self.ffn2 = TransformerFFN(embed_dim, embed_dim * 2, normalization=normalization) def forward(self, x1, x2, edge_emb, edges): h1 = self.hgnn1(x1, x2, edge_emb, edges) - h1 = self.norm1(h1 + x1) + h1 = self.ffn1(h1, x1) h2 = self.hgnn2(x2, x1, edge_emb.transpose(1, 2), edges.transpose(1, 2)) - h2 = self.norm2(h2 + x2) + h2 = self.ffn2(h2, x2) return h1, h2 @@ -102,27 +102,28 @@ def __init__( self, embed_dim: int, num_layers: int = 2, + normalization: str = "batch", init_embedding=None, - edge_key: str = "ops_ma_adj", - edge_weights_key: str = "proc_times", - linear_bias: bool = False, + env_name: str = "fjsp", + **init_embedding_kwargs, ) -> None: super().__init__() if init_embedding is None: - init_embedding = env_init_embedding("fjsp", {"embed_dim": embed_dim}) - self.init_embedding = init_embedding + init_embedding_kwargs["embed_dim"] = embed_dim + init_embedding = env_init_embedding(env_name, init_embedding_kwargs) - self.edge_key = edge_key - self.edge_weights_key = edge_weights_key + self.init_embedding = init_embedding self.num_layers = num_layers - self.layers = nn.ModuleList([HetGNNBlock(embed_dim) for _ in range(num_layers)]) + self.layers = nn.ModuleList( + [HetGNNBlock(embed_dim, normalization) for _ in range(num_layers)] + ) def forward(self, td): - edges = td[self.edge_key] - bs, n_rows, n_cols = edges.shape - row_emb, col_emb, edge_emb = self.init_embedding(td) + row_emb, col_emb, edge_emb, edges = self.init_embedding(td) + # perform sanity check to validate correct order of row and col embeddings + n_rows, n_cols = edges.shape[1:] assert row_emb.size(1) == n_rows, "incorrect number of row embeddings" assert col_emb.size(1) == n_cols, "incorrect number of column embeddings" diff --git a/rl4co/models/nn/ops.py b/rl4co/models/nn/ops.py index 044ce8cf..f6f774fe 100644 --- a/rl4co/models/nn/ops.py +++ b/rl4co/models/nn/ops.py @@ -1,8 +1,12 @@ +import math + from typing import Tuple, Union import torch import torch.nn as nn +from rl4co.utils.ops import gather_by_index + class SkipConnection(nn.Module): def __init__(self, module): @@ -79,3 +83,55 @@ def forward(self, hidden: torch.Tensor, seq_pos) -> torch.Tensor: ) hidden = hidden + pes return self.dropout(hidden) + + +class TransformerFFN(nn.Module): + def __init__(self, embed_dim, feed_forward_hidden, normalization="batch") -> None: + super().__init__() + + self.ops = nn.ModuleDict( + { + "norm1": Normalization(embed_dim, normalization), + "ffn": nn.Sequential( + nn.Linear(embed_dim, feed_forward_hidden), + nn.ReLU(), + nn.Linear(feed_forward_hidden, embed_dim), + ), + "norm2": Normalization(embed_dim, normalization), + } + ) + + def forward(self, x, x_old): + x = self.ops["norm1"](x_old + x) + x = self.ops["norm2"](x + self.ops["ffn"](x)) + + return x + + +class RandomEncoding(nn.Module): + """This is like torch.nn.Embedding but with rows of embeddings are randomly + permuted in each forward pass before lookup operation. This might be useful + in cases where classes have no fixed meaning but rather indicate a connection + between different elements in a sequence. Reference is the MatNet model. + """ + + def __init__(self, embed_dim: int, max_classes: int = 100): + super().__init__() + self.embed_dim = embed_dim + self.max_classes = max_classes + rand_emb = torch.rand(max_classes, self.embed_dim) + self.register_buffer("emb", rand_emb) + + def forward(self, hidden: torch.Tensor, classes=None) -> torch.Tensor: + b, s, _ = hidden.shape + if classes is None: + classes = torch.eye(s).unsqueeze(0).expand(b, s) + assert ( + classes.max() < self.max_classes + ), "number of classes larger than embedding table" + classes = classes.unsqueeze(-1).expand(-1, -1, self.embed_dim) + rand_idx = torch.rand(b, self.max_classes).argsort(dim=1) + embs_permuted = self.emb[rand_idx] + rand_emb = gather_by_index(embs_permuted, classes, dim=1) + hidden = hidden + rand_emb + return hidden diff --git a/rl4co/models/rl/__init__.py b/rl4co/models/rl/__init__.py index c78ff706..1a3bf7e2 100644 --- a/rl4co/models/rl/__init__.py +++ b/rl4co/models/rl/__init__.py @@ -2,4 +2,5 @@ from rl4co.models.rl.common.base import RL4COLitModule from rl4co.models.rl.ppo.n_step_ppo import n_step_PPO from rl4co.models.rl.ppo.ppo import PPO +from rl4co.models.rl.ppo.stepwise_ppo import StepwisePPO from rl4co.models.rl.reinforce.reinforce import REINFORCE diff --git a/rl4co/models/rl/common/utils.py b/rl4co/models/rl/common/utils.py new file mode 100644 index 00000000..b23149f7 --- /dev/null +++ b/rl4co/models/rl/common/utils.py @@ -0,0 +1,46 @@ +import torch + + +class RewardScaler: + """This class calculates the running mean and variance of a stepwise observed + quantity, like the RL reward / advantage using the Welford online algorithm. + The mean and variance are either used to standardize the input (scale='norm') or + to scale it (scale='scale'). + + Args: + scale: None | 'scale' | 'mean': specifies how to transform the input; defaults to None + """ + + def __init__(self, scale: str = None): + self.scale = scale + self.count = 0 + self.mean = 0 + self.M2 = 0 + + def __call__(self, scores: torch.Tensor): + if self.scale is None: + return scores + # Score scaling + self.update(scores) + tensor_to_kwargs = dict(dtype=scores.dtype, device=scores.device) + std = (self.M2 / (self.count - 1)).float().sqrt() + score_scaling_factor = std.to(**tensor_to_kwargs) + torch.finfo(scores.dtype).eps + if self.scale == "norm": + scores = (scores - self.mean.to(**tensor_to_kwargs)) / score_scaling_factor + elif self.scale == "scale": + scores /= score_scaling_factor + else: + raise ValueError("unknown scaling operation requested: %s" % self.scale) + return scores + + @torch.no_grad() + def update(self, batch: torch.Tensor): + batch = batch.reshape(-1) + self.count += len(batch) + + # newvalues - oldMean + delta = batch - self.mean + self.mean += (delta / self.count).sum() + # newvalues - newMeant + delta2 = batch - self.mean + self.M2 += (delta * delta2).sum() diff --git a/rl4co/models/rl/ppo/stepwise_ppo.py b/rl4co/models/rl/ppo/stepwise_ppo.py new file mode 100644 index 00000000..98186ea1 --- /dev/null +++ b/rl4co/models/rl/ppo/stepwise_ppo.py @@ -0,0 +1,168 @@ +import copy + +from typing import Any + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from torchrl.data.replay_buffers import ( + LazyTensorStorage, + ListStorage, + SamplerWithoutReplacement, + TensorDictReplayBuffer, +) + +from rl4co.envs.common.base import RL4COEnvBase +from rl4co.models.rl.common.base import RL4COLitModule +from rl4co.models.rl.common.utils import RewardScaler +from rl4co.utils.pylogger import get_pylogger + +log = get_pylogger(__name__) + + +def make_replay_buffer(buffer_size, batch_size, device="cpu"): + if device == "cpu": + storage = LazyTensorStorage(buffer_size, device="cpu") + else: + storage = ListStorage(buffer_size) + return TensorDictReplayBuffer( + storage=storage, + batch_size=batch_size, + sampler=SamplerWithoutReplacement(drop_last=True), + ) + + +class StepwisePPO(RL4COLitModule): + def __init__( + self, + env: RL4COEnvBase, + policy: nn.Module, + clip_range: float = 0.2, # epsilon of PPO + update_timestep: int = 1, + buffer_size: int = 100_000, + ppo_epochs: int = 2, # inner epoch, K + batch_size: int = 256, + mini_batch_size: int = 256, + vf_lambda: float = 0.5, # lambda of Value function fitting + entropy_lambda: float = 0.01, # lambda of entropy bonus + max_grad_norm: float = 0.5, # max gradient norm + buffer_storage_device: str = "gpu", + metrics: dict = { + "train": ["loss", "surrogate_loss", "value_loss", "entropy"], + }, + reward_scale: str = None, + **kwargs, + ): + super().__init__(env, policy, metrics=metrics, batch_size=batch_size, **kwargs) + + self.policy_old = copy.deepcopy(self.policy) + self.automatic_optimization = False # PPO uses custom optimization routine + self.rb = make_replay_buffer(buffer_size, mini_batch_size, buffer_storage_device) + self.scaler = RewardScaler(reward_scale) + + self.ppo_cfg = { + "clip_range": clip_range, + "ppo_epochs": ppo_epochs, + "update_timestep": update_timestep, + "mini_batch_size": mini_batch_size, + "vf_lambda": vf_lambda, + "entropy_lambda": entropy_lambda, + "max_grad_norm": max_grad_norm, + } + + def update(self, device): + outs = [] + # PPO inner epoch + for _ in range(self.ppo_cfg["ppo_epochs"]): + for sub_td in self.rb: + sub_td = sub_td.to(device) + previous_reward = sub_td["reward"].view(-1, 1) + previous_logp = sub_td["logprobs"] + + logprobs, value_pred, entropy = self.policy.evaluate(sub_td) + + ratios = torch.exp(logprobs - previous_logp) + + advantages = torch.squeeze(previous_reward - value_pred.detach(), 1) + surr1 = ratios * advantages + surr2 = ( + torch.clamp( + ratios, + 1 - self.ppo_cfg["clip_range"], + 1 + self.ppo_cfg["clip_range"], + ) + * advantages + ) + surrogate_loss = -torch.min(surr1, surr2).mean() + + # compute value function loss + value_loss = F.mse_loss(value_pred, previous_reward) + + # compute total loss + loss = ( + surrogate_loss + + self.ppo_cfg["vf_lambda"] * value_loss + - self.ppo_cfg["entropy_lambda"] * entropy.mean() + ) + + # perform manual optimization following the Lightning routine + # https://lightning.ai/docs/pytorch/stable/common/optimization.html + + opt = self.optimizers() + opt.zero_grad() + self.manual_backward(loss) + if self.ppo_cfg["max_grad_norm"] is not None: + self.clip_gradients( + opt, + gradient_clip_val=self.ppo_cfg["max_grad_norm"], + gradient_clip_algorithm="norm", + ) + opt.step() + + out = { + "reward": previous_reward.mean(), + "loss": loss, + "surrogate_loss": surrogate_loss, + "value_loss": value_loss, + "entropy": entropy.mean(), + } + + outs.append(out) + # Copy new weights into old policy: + self.policy_old.load_state_dict(self.policy.state_dict()) + outs = {k: torch.stack([dic[k] for dic in outs], dim=0) for k in outs[0]} + return outs + + def shared_step( + self, batch: Any, batch_idx: int, phase: str, dataloader_idx: int = None + ): + next_td = self.env.reset(batch) + device = next_td.device + if phase == "train": + while not next_td["done"].all(): + with torch.no_grad(): + td = self.policy_old.act(next_td, self.env, phase="train") + + assert self.env._torchrl_mode, "Use torchrl mode in stepwise PPO" + td = self.env.step(td) + next_td = td.pop("next") + reward = self.env.get_reward(next_td, None) + reward = self.scaler(reward) + + td.set("reward", reward) + # add tensordict with action, logprobs and reward information to buffer + self.rb.extend(td) + + # if iter mod x = 0 then update the policy (x = 1 in paper) + if batch_idx % self.ppo_cfg["update_timestep"] == 0: + out = self.update(device) + self.rb.empty() + + else: + out = self.policy.generate( + next_td, self.env, phase=phase, select_best=phase != "train" + ) + + metrics = self.log_metrics(out, phase, dataloader_idx=dataloader_idx) + return {"loss": out.get("loss", None), **metrics} diff --git a/rl4co/models/rl/reinforce/reinforce.py b/rl4co/models/rl/reinforce/reinforce.py index 2a153391..269aaaff 100644 --- a/rl4co/models/rl/reinforce/reinforce.py +++ b/rl4co/models/rl/reinforce/reinforce.py @@ -10,6 +10,7 @@ from rl4co.envs.common.base import RL4COEnvBase from rl4co.models.rl.common.base import RL4COLitModule +from rl4co.models.rl.common.utils import RewardScaler from rl4co.models.rl.reinforce.baselines import REINFORCEBaseline, get_reinforce_baseline from rl4co.utils.lightning import get_lightning_device from rl4co.utils.pylogger import get_pylogger @@ -35,6 +36,7 @@ def __init__( policy: nn.Module, baseline: Union[REINFORCEBaseline, str] = "rollout", baseline_kwargs: dict = {}, + reward_scale: str = None, **kwargs, ): super().__init__(env, policy, **kwargs) @@ -52,6 +54,7 @@ def __init__( if baseline_kwargs != {}: log.warning("baseline_kwargs is ignored when baseline is not a string") self.baseline = baseline + self.advantage_scaler = RewardScaler(reward_scale) def shared_step( self, batch: Any, batch_idx: int, phase: str, dataloader_idx: int = None @@ -98,6 +101,7 @@ def calculate_loss( # Main loss function advantage = reward - bl_val # advantage = reward - baseline + advantage = self.advantage_scaler(advantage) reinforce_loss = -(advantage * log_likelihood).mean() loss = reinforce_loss + bl_loss policy_out.update( @@ -197,7 +201,7 @@ def load_from_checkpoint( loaded.setup() loaded.post_setup_hook() # load baseline state dict - state_dict = torch.load(checkpoint_path)["state_dict"] + state_dict = torch.load(checkpoint_path, map_location=map_location)["state_dict"] # get only baseline parameters state_dict = {k: v for k, v in state_dict.items() if "baseline" in k} state_dict = {k.replace("baseline.", "", 1): v for k, v in state_dict.items()} diff --git a/rl4co/models/zoo/__init__.py b/rl4co/models/zoo/__init__.py index 8e6dcddd..cb1a21ef 100644 --- a/rl4co/models/zoo/__init__.py +++ b/rl4co/models/zoo/__init__.py @@ -10,13 +10,19 @@ HeterogeneousAttentionModel, HeterogeneousAttentionModelPolicy, ) -from rl4co.models.zoo.hetgnn import HetGNNModel +from rl4co.models.zoo.l2d import ( + L2DAttnPolicy, + L2DModel, + L2DPolicy, + L2DPolicy4PPO, + L2DPPOModel, +) from rl4co.models.zoo.matnet import MatNet, MatNetPolicy from rl4co.models.zoo.mdam import MDAM, MDAMPolicy +from rl4co.models.zoo.mvmoe import MVMoE_AM, MVMoE_POMO from rl4co.models.zoo.n2s import N2S, N2SPolicy from rl4co.models.zoo.nargnn import NARGNNPolicy from rl4co.models.zoo.polynet import PolyNet from rl4co.models.zoo.pomo import POMO from rl4co.models.zoo.ptrnet import PointerNetwork, PointerNetworkPolicy from rl4co.models.zoo.symnco import SymNCO, SymNCOPolicy -from rl4co.models.zoo.mvmoe import MVMoE_POMO, MVMoE_AM diff --git a/rl4co/models/zoo/am/decoder.py b/rl4co/models/zoo/am/decoder.py index 731c076f..61600050 100644 --- a/rl4co/models/zoo/am/decoder.py +++ b/rl4co/models/zoo/am/decoder.py @@ -34,7 +34,7 @@ def fields(self): def batchify(self, num_starts): new_embs = [] for emb in self.fields: - if isinstance(emb, Tensor): + if isinstance(emb, Tensor) or isinstance(emb, TensorDict): new_embs.append(batchify(emb, num_starts)) else: new_embs.append(emb) @@ -108,7 +108,9 @@ def __init__( if pointer is None: # MHA with Pointer mechanism (https://arxiv.org/abs/1506.03134) - pointer_attn_class = PointerAttention if moe_kwargs is None else PointerAttnMoE + pointer_attn_class = ( + PointerAttention if moe_kwargs is None else PointerAttnMoE + ) pointer = pointer_attn_class( embed_dim, num_heads, diff --git a/rl4co/models/zoo/hetgnn/__init__.py b/rl4co/models/zoo/hetgnn/__init__.py deleted file mode 100644 index f98562b4..00000000 --- a/rl4co/models/zoo/hetgnn/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .model import HetGNNModel diff --git a/rl4co/models/zoo/hetgnn/decoder.py b/rl4co/models/zoo/hetgnn/decoder.py deleted file mode 100644 index 68bf1d36..00000000 --- a/rl4co/models/zoo/hetgnn/decoder.py +++ /dev/null @@ -1,51 +0,0 @@ -import torch -import torch.nn as nn - -from rl4co.models.common.constructive.autoregressive import AutoregressiveDecoder -from rl4co.models.nn.mlp import MLP -from rl4co.utils.ops import batchify, gather_by_index - - -class HetGNNDecoder(AutoregressiveDecoder): - def __init__( - self, embed_dim, feed_forward_hidden_dim: int = 64, feed_forward_layers: int = 2 - ) -> None: - super().__init__() - self.mlp = MLP( - input_dim=2 * embed_dim, - output_dim=1, - num_neurons=[feed_forward_hidden_dim] * feed_forward_layers, - ) - self.dummy = nn.Parameter(torch.rand(2 * embed_dim)) - - def pre_decoder_hook(self, td, env, hidden, num_starts): - return td, env, hidden - - def forward(self, td, hidden, num_starts): - if num_starts > 1: - hidden = tuple(map(lambda x: batchify(x, num_starts), hidden)) - - ma_emb, ops_emb = hidden - bs, n_rows, emb_dim = ma_emb.shape - - # (bs, n_jobs, emb) - job_emb = gather_by_index(ops_emb, td["next_op"], squeeze=False) - - # (bs, n_jobs, n_ma, emb) - job_emb_expanded = job_emb.unsqueeze(2).expand(-1, -1, n_rows, -1) - ma_emb_expanded = ma_emb.unsqueeze(1).expand_as(job_emb_expanded) - - # Input of actor MLP - # shape: [bs, num_jobs * n_ma, 2*emb] - h_actions = torch.cat((job_emb_expanded, ma_emb_expanded), dim=-1).flatten(1, 2) - no_ops = self.dummy[None, None].expand(bs, 1, -1) # [bs, 1, 2*emb_dim] - # [bs, num_jobs * n_ma + 1, 2*emb_dim] - h_actions_w_noop = torch.cat((no_ops, h_actions), 1) - - # (b, j*m) - mask = td["action_mask"] - - # (b, j*m) - logits = self.mlp(h_actions_w_noop).squeeze(-1) - - return logits, mask diff --git a/rl4co/models/zoo/hetgnn/model.py b/rl4co/models/zoo/hetgnn/model.py deleted file mode 100644 index 40f27de2..00000000 --- a/rl4co/models/zoo/hetgnn/model.py +++ /dev/null @@ -1,38 +0,0 @@ -from typing import Union - -from rl4co.envs.common.base import RL4COEnvBase -from rl4co.models.rl import REINFORCE -from rl4co.models.rl.reinforce.baselines import REINFORCEBaseline - -from .policy import HetGNNPolicy - - -class HetGNNModel(REINFORCE): - """Heterogenous Graph Neural Network Model as described by Song et al. (2022): - 'Flexible Job Shop Scheduling via Graph Neural Network and Deep Reinforcement Learning' - - Args: - env: Environment to use for the algorithm - policy: Policy to use for the algorithm - baseline: REINFORCE baseline. Defaults to rollout (1 epoch of exponential, then greedy rollout baseline) - policy_kwargs: Keyword arguments for policy - baseline_kwargs: Keyword arguments for baseline - **kwargs: Keyword arguments passed to the superclass - """ - - def __init__( - self, - env: RL4COEnvBase, - policy: HetGNNPolicy = None, - baseline: Union[REINFORCEBaseline, str] = "rollout", - policy_kwargs={}, - baseline_kwargs={}, - **kwargs, - ): - assert ( - env.name == "fjsp" - ), "HetGNNModel currently only works for FJSP (Flexible Job-Shop Scheduling Problem)" - if policy is None: - policy = HetGNNPolicy(env_name=env.name, **policy_kwargs) - - super().__init__(env, policy, baseline, baseline_kwargs, **kwargs) diff --git a/rl4co/models/zoo/hetgnn/policy.py b/rl4co/models/zoo/hetgnn/policy.py deleted file mode 100644 index c51dc30e..00000000 --- a/rl4co/models/zoo/hetgnn/policy.py +++ /dev/null @@ -1,99 +0,0 @@ -from typing import Optional - -import torch.nn as nn - -from rl4co.models.common.constructive.autoregressive import ( - AutoregressiveDecoder, - AutoregressiveEncoder, - AutoregressivePolicy, -) -from rl4co.utils.pylogger import get_pylogger - -from .decoder import HetGNNDecoder -from .encoder import HetGNNEncoder - -log = get_pylogger(__name__) - - -class HetGNNPolicy(AutoregressivePolicy): - """ - Base Non-autoregressive policy for NCO construction methods. - This creates a heatmap of NxN for N nodes (i.e., heuristic) that models the probability to go from one node to another for all nodes. - - The policy performs the following steps: - 1. Encode the environment initial state into node embeddings - 2. Decode (non-autoregressively) to construct the solution to the NCO problem - - Warning: - The effectiveness of the non-autoregressive approach can vary significantly across different problem types and configurations. - It may require careful tuning of the model architecture and decoding strategy to achieve competitive results. - - Args: - encoder: Encoder module. Can be passed by sub-classes - decoder: Decoder module. Note that this moule defaults to the non-autoregressive decoder - embed_dim: Dimension of the embeddings - env_name: Name of the environment used to initialize embeddings - init_embedding: Model to use for the initial embedding. If None, use the default embedding for the environment - edge_embedding: Model to use for the edge embedding. If None, use the default embedding for the environment - graph_network: Model to use for the graph network. If None, use the default embedding for the environment - heatmap_generator: Model to use for the heatmap generator. If None, use the default embedding for the environment - num_layers_heatmap_generator: Number of layers in the heatmap generator - num_layers_graph_encoder: Number of layers in the graph encoder - act_fn: Activation function to use in the encoder - agg_fn: Aggregation function to use in the encoder - linear_bias: Whether to use bias in the encoder - train_decode_type: Type of decoding during training - val_decode_type: Type of decoding during validation - test_decode_type: Type of decoding during testing - **constructive_policy_kw: Unused keyword arguments - """ - - def __init__( - self, - encoder: Optional[AutoregressiveEncoder] = None, - decoder: Optional[AutoregressiveDecoder] = None, - embed_dim: int = 64, - num_encoder_layers: int = 2, - env_name: str = "fjsp", - init_embedding: Optional[nn.Module] = None, - linear_bias: bool = True, - train_decode_type: str = "sampling", - val_decode_type: str = "greedy", - test_decode_type: str = "multistart_sampling", - **constructive_policy_kw, - ): - if len(constructive_policy_kw) > 0: - log.warn(f"Unused kwargs: {constructive_policy_kw}") - - if encoder is None: - encoder = HetGNNEncoder( - embed_dim=embed_dim, - num_layers=num_encoder_layers, - init_embedding=init_embedding, - linear_bias=linear_bias, - ) - - # The decoder generates logits given the current td and heatmap - if decoder is None: - decoder = HetGNNDecoder( - embed_dim=embed_dim, - feed_forward_hidden_dim=embed_dim, - feed_forward_layers=2, - ) - else: - # check if the decoder has trainable parameters - if any(p.requires_grad for p in decoder.parameters()): - log.error( - "The decoder contains trainable parameters. This should not happen in a non-autoregressive policy." - ) - - # Pass to constructive policy - super(HetGNNPolicy, self).__init__( - encoder=encoder, - decoder=decoder, - env_name=env_name, - train_decode_type=train_decode_type, - val_decode_type=val_decode_type, - test_decode_type=test_decode_type, - **constructive_policy_kw, - ) diff --git a/rl4co/models/zoo/l2d/__init__.py b/rl4co/models/zoo/l2d/__init__.py new file mode 100644 index 00000000..398dea98 --- /dev/null +++ b/rl4co/models/zoo/l2d/__init__.py @@ -0,0 +1,2 @@ +from .model import L2DModel, L2DPPOModel +from .policy import L2DAttnPolicy, L2DPolicy, L2DPolicy4PPO diff --git a/rl4co/models/zoo/l2d/decoder.py b/rl4co/models/zoo/l2d/decoder.py new file mode 100644 index 00000000..b0ab3041 --- /dev/null +++ b/rl4co/models/zoo/l2d/decoder.py @@ -0,0 +1,390 @@ +import abc + +from typing import Any, Tuple + +import torch +import torch.nn as nn + +from einops import einsum, rearrange +from tensordict import TensorDict +from torch import Tensor + +from rl4co.models.common.constructive.autoregressive import AutoregressiveDecoder +from rl4co.models.nn.attention import PointerAttention +from rl4co.models.nn.env_embeddings.context import SchedulingContext +from rl4co.models.nn.env_embeddings.dynamic import JSSPDynamicEmbedding +from rl4co.models.nn.graph.hgnn import HetGNNEncoder +from rl4co.models.nn.mlp import MLP +from rl4co.models.zoo.am.decoder import AttentionModelDecoder, PrecomputedCache +from rl4co.utils.ops import batchify, gather_by_index + +from .encoder import GCN4JSSP + + +class L2DActor(nn.Module, metaclass=abc.ABCMeta): + """Base decoder model for actor in L2D. The actor is responsible for generating the logits for the action + similar to the decoder in autoregressive models. Since the decoder in L2D can have the additional purpose + of extracting features (i.e. encoding the environment in ever iteration), we need an additional actor class. + This function serves as template for such actor classes in L2D + """ + + @abc.abstractmethod + def forward( + self, td: TensorDict, hidden: Any = None, num_starts: int = 0 + ) -> Tuple[Tensor, Tensor]: + """Obtain logits for current action to the next ones + + Args: + td: TensorDict containing the input data + hidden: Hidden state from the encoder. Can be any type + num_starts: Number of starts for multistart decoding + + Returns: + Tuple containing the logits and the action mask + """ + raise NotImplementedError("Implement me in subclass!") + + def pre_decoder_hook( + self, td: TensorDict, env=None, hidden: Any = None, num_starts: int = 0 + ) -> Tuple[TensorDict, Any]: + """By default, we only require the input for the actor to be a tuple + (in JSSP we only have operation embeddings but in FJSP we have operation + and machine embeddings. By expecting a tuple we can generalize things.) + + Args: + td: TensorDict containing the input data + hidden: Hidden state from the encoder + num_starts: Number of starts for multistart decoding + + Returns: + Tuple containing the updated hidden state(s) and the input TensorDict + """ + + hidden = (hidden,) if not isinstance(hidden, tuple) else hidden + + if num_starts > 1: + # NOTE: when using pomo, we need this + hidden = tuple(map(lambda x: batchify(x, num_starts), hidden)) + + return td, env, hidden + + +class JSSPActor(L2DActor): + def __init__( + self, + embed_dim: int, + hidden_dim: int, + hidden_layers: int = 2, + het_emb: bool = False, + check_nan: bool = True, + ) -> None: + super().__init__() + + input_dim = (1 + int(het_emb)) * embed_dim + self.mlp = MLP( + input_dim=input_dim, + output_dim=1, + num_neurons=[hidden_dim] * hidden_layers, + hidden_act="ReLU", + out_act="Identity", + input_norm="None", + output_norm="None", + ) + self.het_emb = het_emb + self.dummy = nn.Parameter(torch.rand(input_dim)) + self.check_nan = check_nan + + def forward(self, td, op_emb, ma_emb=None): + bs = td.size(0) + # (bs, n_j) + next_op = td["next_op"] + # (bs, n_j, emb) + job_emb = gather_by_index(op_emb, next_op, dim=1) + if ma_emb is not None: + ma_emb_per_op = einsum(td["ops_ma_adj"], ma_emb, "b m o, b m e -> b o e") + # (bs, n_j, emb) + ma_emb_per_job = gather_by_index(ma_emb_per_op, next_op, dim=1) + # (bs, n_j, 2 * emb) + job_emb = torch.cat((job_emb, ma_emb_per_job), dim=2) + # (bs, n_j, 2 * emb) + no_ops = self.dummy[None, None].expand(bs, 1, -1) + # (bs, 1 + n_j, 2 * emb) + all_actions = torch.cat((no_ops, job_emb), 1) + # (bs, 1 + n_j) + logits = self.mlp(all_actions).squeeze(2) + + if self.check_nan: + assert not torch.isnan(logits).any(), "Logits contain NaNs" + + # (b, 1 + j) + mask = td["action_mask"] + + return logits, mask + + +class FJSPActor(L2DActor): + def __init__( + self, + embed_dim: int, + hidden_dim: int, + hidden_layers: int = 2, + check_nan: bool = True, + ) -> None: + super().__init__() + self.mlp = MLP( + input_dim=2 * embed_dim, + output_dim=1, + num_neurons=[hidden_dim] * hidden_layers, + hidden_act="ReLU", + out_act="Identity", + input_norm="None", + output_norm="None", + ) + self.dummy = nn.Parameter(torch.rand(2 * embed_dim)) + self.check_nan = check_nan + + def forward(self, td, ops_emb, ma_emb): + bs, n_ma = ma_emb.shape[:2] + # (bs, n_jobs, emb) + job_emb = gather_by_index(ops_emb, td["next_op"], squeeze=False) + # (bs, n_jobs, n_ma, emb) + job_emb_expanded = job_emb.unsqueeze(2).expand(-1, -1, n_ma, -1) + ma_emb_expanded = ma_emb.unsqueeze(1).expand_as(job_emb_expanded) + # (bs, num_jobs * n_ma, 2*emb) + h_actions = torch.cat((job_emb_expanded, ma_emb_expanded), dim=-1).flatten(1, 2) + # (bs, 1, 2*emb_dim) + no_ops = self.dummy[None, None].expand(bs, 1, -1) + # (bs, num_jobs * n_ma + 1, 2*emb_dim) + h_actions_w_noop = torch.cat((no_ops, h_actions), 1) + # (b, j*m) + logits = self.mlp(h_actions_w_noop).squeeze(-1) + + if self.check_nan: + assert not torch.isnan(logits).any(), "Logits contain NaNs" + # (b, 1 + j) + mask = td["action_mask"] + return logits, mask + + +class L2DDecoder(AutoregressiveDecoder): + # feature extractor + actor + def __init__( + self, + env_name: str = "jssp", + feature_extractor: nn.Module = None, + actor: nn.Module = None, + init_embedding: nn.Module = None, + embed_dim: int = 128, + actor_hidden_dim: int = 128, + actor_hidden_layers: int = 2, + num_encoder_layers: int = 3, + num_heads: int = 8, + normalization: str = "batch", + het_emb: bool = False, + stepwise: bool = False, + scaling_factor: int = 1000, + ): + super(L2DDecoder, self).__init__() + + if feature_extractor is None and stepwise: + if env_name == "fjsp" or (het_emb and env_name == "jssp"): + feature_extractor = HetGNNEncoder( + env_name=env_name, + embed_dim=embed_dim, + num_layers=num_encoder_layers, + normalization=normalization, + init_embedding=init_embedding, + scaling_factor=scaling_factor, + ) + else: + feature_extractor = GCN4JSSP( + embed_dim, + num_encoder_layers, + init_embedding=init_embedding, + scaling_factor=scaling_factor, + ) + + self.feature_extractor = feature_extractor + + if actor is None: + if env_name == "fjsp": + actor = FJSPActor( + embed_dim=embed_dim, + hidden_dim=actor_hidden_dim, + hidden_layers=actor_hidden_layers, + ) + else: + actor = JSSPActor( + embed_dim=embed_dim, + hidden_dim=actor_hidden_dim, + hidden_layers=actor_hidden_layers, + het_emb=het_emb, + ) + + self.actor = actor + + def forward(self, td, hidden, num_starts): + if hidden is None: + # NOTE in case we have multiple starts, td is batchified + # (through decoding strategy pre decoding hook). Thus the + # embeddings from feature_extractor have the correct shape + num_starts = 0 + # (bs, n_j * n_ops, e), (bs, n_m, e) + hidden, _ = self.feature_extractor(td) + + td, _, hidden = self.actor.pre_decoder_hook(td, None, hidden, num_starts) + + # (bs, n_j, e) + logits, mask = self.actor(td, *hidden) + + return logits, mask + + +class L2DAttnPointer(PointerAttention): + def __init__( + self, + env_name: str, + embed_dim: int, + num_heads: int, + out_bias: bool = False, + check_nan: bool = True, + ): + super().__init__( + embed_dim=embed_dim, + num_heads=num_heads, + mask_inner=False, + out_bias=out_bias, + check_nan=check_nan, + ) + self.env_name = env_name + + def forward(self, query, key, value, logit_key, attn_mask=None): + # bs = query.size(0) + # (b m j) + logits = super().forward(query, key, value, logit_key, attn_mask=attn_mask) + if self.env_name == "jssp": + # (b j) + logits = logits.sum(1) + elif self.env_name == "fjsp": + no_op_logits = logits[..., 0].sum(1, keepdims=True) + logits = rearrange(logits[..., 1:], "b m j -> b (j m)") + logits = torch.cat((no_op_logits, logits), dim=1) + + return logits + + +class AttnActor(AttentionModelDecoder): + def __init__( + self, + embed_dim: int = 128, + num_heads: int = 8, + env_name: str = "tsp", + context_embedding: nn.Module = None, + dynamic_embedding: nn.Module = None, + mask_inner: bool = True, + out_bias_pointer_attn: bool = False, + linear_bias: bool = False, + use_graph_context: bool = True, + check_nan: bool = True, + sdpa_fn: callable = None, + pointer: nn.Module = None, + moe_kwargs: dict = None, + ): + super().__init__( + embed_dim, + num_heads, + env_name, + context_embedding, + dynamic_embedding, + mask_inner, + out_bias_pointer_attn, + linear_bias, + use_graph_context, + check_nan, + sdpa_fn, + pointer, + moe_kwargs, + ) + + def pre_decoder_hook( + self, td: TensorDict, env=None, hidden: Any = None, num_starts: int = 0 + ) -> Tuple[TensorDict, Any]: + cache = self._precompute_cache(hidden, num_starts=num_starts) + return td, env, (cache,) + + +class L2DAttnActor(AttnActor): + def __init__( + self, + embed_dim: int = 128, + num_heads: int = 8, + env_name: str = "jssp", + scaling_factor: int = 1000, + stepwise: bool = False, + ): + context_embedding = SchedulingContext(embed_dim, scaling_factor=scaling_factor) + if stepwise: + # in a stepwise encoding setting, the embeddings contain all current information + dynamic_embedding = None + else: + # otherwise we might want to update the static embeddings using dynamic updates + dynamic_embedding = JSSPDynamicEmbedding( + embed_dim, scaling_factor=scaling_factor + ) + pointer = L2DAttnPointer(env_name, embed_dim, num_heads, check_nan=False) + + super().__init__( + embed_dim=embed_dim, + num_heads=num_heads, + env_name=env_name, + context_embedding=context_embedding, + dynamic_embedding=dynamic_embedding, + pointer=pointer, + ) + self.dummy = nn.Parameter(torch.rand(1, embed_dim)) + + def _compute_q(self, cached: PrecomputedCache, td: TensorDict): + embeddings = cached.node_embeddings + ma_embs = embeddings["machine_embeddings"] + return self.context_embedding(ma_embs, td) + + def _compute_kvl(self, cached: PrecomputedCache, td: TensorDict): + glimpse_k_stat, glimpse_v_stat, logit_k_stat = ( + gather_by_index(cached.glimpse_key, td["next_op"], dim=1), + gather_by_index(cached.glimpse_val, td["next_op"], dim=1), + gather_by_index(cached.logit_key, td["next_op"], dim=1), + ) + # Compute dynamic embeddings and add to static embeddings + glimpse_k_dyn, glimpse_v_dyn, logit_k_dyn = self.dynamic_embedding(td, cached) + glimpse_k = glimpse_k_stat + glimpse_k_dyn + glimpse_v = glimpse_v_stat + glimpse_v_dyn + logit_k = logit_k_stat + logit_k_dyn + + no_ops = self.dummy.unsqueeze(1).expand(td.size(0), 1, -1).to(logit_k) + logit_k = torch.cat((no_ops, logit_k), dim=1) + + return glimpse_k, glimpse_v, logit_k + + def _precompute_cache(self, embeddings: Tuple[torch.Tensor, torch.Tensor], **kwargs): + ops_emb, ma_emb = embeddings + + ( + glimpse_key_fixed, + glimpse_val_fixed, + logit_key, + ) = self.project_node_embeddings( + ops_emb + ).chunk(3, dim=-1) + + embeddings = TensorDict( + {"op_embeddings": ops_emb, "machine_embeddings": ma_emb}, + batch_size=ops_emb.size(0), + ) + # Organize in a dataclass for easy access + return PrecomputedCache( + node_embeddings=embeddings, + graph_context=0, + glimpse_key=glimpse_key_fixed, + glimpse_val=glimpse_val_fixed, + logit_key=logit_key, + ) diff --git a/rl4co/models/zoo/l2d/encoder.py b/rl4co/models/zoo/l2d/encoder.py new file mode 100644 index 00000000..0bc43fa9 --- /dev/null +++ b/rl4co/models/zoo/l2d/encoder.py @@ -0,0 +1,26 @@ +from rl4co.models.nn.env_embeddings.init import JSSPInitEmbedding +from rl4co.models.nn.graph.gcn import GCNEncoder +from rl4co.utils.ops import adj_to_pyg_edge_index + + +class GCN4JSSP(GCNEncoder): + def __init__( + self, + embed_dim: int, + num_layers: int, + init_embedding=None, + **init_embedding_kwargs, + ): + def edge_idx_fn(td, _): + return adj_to_pyg_edge_index(td["adjacency"]) + + if init_embedding is None: + init_embedding = JSSPInitEmbedding(embed_dim, **init_embedding_kwargs) + + super().__init__( + env_name="jssp", + embed_dim=embed_dim, + num_layers=num_layers, + edge_idx_fn=edge_idx_fn, + init_embedding=init_embedding, + ) diff --git a/rl4co/models/zoo/l2d/model.py b/rl4co/models/zoo/l2d/model.py new file mode 100644 index 00000000..b70784b1 --- /dev/null +++ b/rl4co/models/zoo/l2d/model.py @@ -0,0 +1,69 @@ +from typing import Union + +from rl4co.envs.common.base import RL4COEnvBase +from rl4co.models.rl import REINFORCE, StepwisePPO +from rl4co.models.rl.reinforce.baselines import REINFORCEBaseline + +from .policy import L2DPolicy, L2DPolicy4PPO + + +class L2DPPOModel(StepwisePPO): + """Learning2Dispatch model by Zhang et al. (2020): + 'Learning to Dispatch for Job Shop Scheduling via Deep Reinforcement Learning' + + Args: + env: Environment to use for the algorithm + policy: Policy to use for the algorithm + baseline: REINFORCE baseline. Defaults to rollout (1 epoch of exponential, then greedy rollout baseline) + policy_kwargs: Keyword arguments for policy + baseline_kwargs: Keyword arguments for baseline + **kwargs: Keyword arguments passed to the superclass + """ + + def __init__( + self, + env: RL4COEnvBase, + policy: L2DPolicy = None, + policy_kwargs={}, + **kwargs, + ): + assert env.name in [ + "fjsp", + "jssp", + ], "L2DModel currently only works for Job-Shop Scheduling Problems" + if policy is None: + policy = L2DPolicy4PPO(env_name=env.name, **policy_kwargs) + + super().__init__(env, policy, **kwargs) + + +class L2DModel(REINFORCE): + """Learning2Dispatch model by Zhang et al. (2020): + 'Learning to Dispatch for Job Shop Scheduling via Deep Reinforcement Learning' + + Args: + env: Environment to use for the algorithm + policy: Policy to use for the algorithm + baseline: REINFORCE baseline. Defaults to rollout (1 epoch of exponential, then greedy rollout baseline) + policy_kwargs: Keyword arguments for policy + baseline_kwargs: Keyword arguments for baseline + **kwargs: Keyword arguments passed to the superclass + """ + + def __init__( + self, + env: RL4COEnvBase, + policy: L2DPolicy = None, + baseline: Union[REINFORCEBaseline, str] = "rollout", + policy_kwargs={}, + baseline_kwargs={}, + **kwargs, + ): + assert env.name in [ + "fjsp", + "jssp", + ], "L2DModel currently only works for Job-Shop Scheduling Problems" + if policy is None: + policy = L2DPolicy(env_name=env.name, **policy_kwargs) + + super().__init__(env, policy, baseline, baseline_kwargs, **kwargs) diff --git a/rl4co/models/zoo/l2d/policy.py b/rl4co/models/zoo/l2d/policy.py new file mode 100644 index 00000000..b4b9b11c --- /dev/null +++ b/rl4co/models/zoo/l2d/policy.py @@ -0,0 +1,248 @@ +from typing import Optional + +import torch +import torch.nn as nn + +from torch.distributions import Categorical + +from rl4co.models.common.constructive.autoregressive import ( + AutoregressiveDecoder, + AutoregressiveEncoder, + AutoregressivePolicy, +) +from rl4co.models.common.constructive.base import NoEncoder +from rl4co.models.nn.env_embeddings.init import FJSPMatNetInitEmbedding +from rl4co.models.nn.graph.hgnn import HetGNNEncoder +from rl4co.models.nn.mlp import MLP +from rl4co.models.zoo.matnet.matnet_w_sa import Encoder +from rl4co.utils.decoding import DecodingStrategy, process_logits +from rl4co.utils.ops import gather_by_index +from rl4co.utils.pylogger import get_pylogger + +from .decoder import L2DAttnActor, L2DDecoder +from .encoder import GCN4JSSP + +log = get_pylogger(__name__) + + +class L2DPolicy(AutoregressivePolicy): + def __init__( + self, + encoder: Optional[AutoregressiveEncoder] = None, + decoder: Optional[AutoregressiveDecoder] = None, + embed_dim: int = 64, + num_encoder_layers: int = 2, + env_name: str = "fjsp", + het_emb: bool = True, + scaling_factor: int = 1000, + init_embedding: Optional[nn.Module] = None, + stepwise_encoding: bool = False, + tanh_clipping: float = 10, + train_decode_type: str = "sampling", + val_decode_type: str = "greedy", + test_decode_type: str = "multistart_sampling", + **constructive_policy_kw, + ): + if len(constructive_policy_kw) > 0: + log.warn(f"Unused kwargs: {constructive_policy_kw}") + + if encoder is None: + if stepwise_encoding: + encoder = NoEncoder() + elif env_name == "fjsp" or (env_name == "jssp" and het_emb): + encoder = HetGNNEncoder( + env_name=env_name, + embed_dim=embed_dim, + num_layers=num_encoder_layers, + normalization="batch", + init_embedding=init_embedding, + scaling_factor=scaling_factor, + ) + else: + encoder = GCN4JSSP( + embed_dim, + num_encoder_layers, + init_embedding=init_embedding, + scaling_factor=scaling_factor, + ) + + # The decoder generates logits given the current td and heatmap + if decoder is None: + decoder = L2DDecoder( + env_name=env_name, + embed_dim=embed_dim, + actor_hidden_dim=embed_dim, + num_encoder_layers=num_encoder_layers, + init_embedding=init_embedding, + het_emb=het_emb, + stepwise=stepwise_encoding, + scaling_factor=scaling_factor, + ) + + # Pass to constructive policy + super(L2DPolicy, self).__init__( + encoder=encoder, + decoder=decoder, + env_name=env_name, + tanh_clipping=tanh_clipping, + train_decode_type=train_decode_type, + val_decode_type=val_decode_type, + test_decode_type=test_decode_type, + **constructive_policy_kw, + ) + + +class L2DAttnPolicy(AutoregressivePolicy): + def __init__( + self, + encoder: Optional[AutoregressiveEncoder] = None, + decoder: Optional[AutoregressiveDecoder] = None, + embed_dim: int = 256, + num_heads: int = 8, + num_encoder_layers: int = 4, + scaling_factor: int = 1000, + env_name: str = "fjsp", + init_embedding: Optional[nn.Module] = None, + tanh_clipping: float = 10, + train_decode_type: str = "sampling", + val_decode_type: str = "greedy", + test_decode_type: str = "multistart_sampling", + **constructive_policy_kw, + ): + if len(constructive_policy_kw) > 0: + log.warn(f"Unused kwargs: {constructive_policy_kw}") + + if encoder is None: + if init_embedding is None: + init_embedding = FJSPMatNetInitEmbedding( + embed_dim, scaling_factor=scaling_factor + ) + + encoder = Encoder( + embed_dim=embed_dim, + num_heads=num_heads, + num_layers=num_encoder_layers, + normalization="batch", + feedforward_hidden=embed_dim * 2, + init_embedding=init_embedding, + ) + + # The decoder generates logits given the current td and heatmap + if decoder is None: + decoder = L2DAttnActor( + env_name=env_name, + embed_dim=embed_dim, + num_heads=num_heads, + scaling_factor=scaling_factor, + stepwise=False, + ) + + # Pass to constructive policy + super(L2DAttnPolicy, self).__init__( + encoder=encoder, + decoder=decoder, + env_name=env_name, + tanh_clipping=tanh_clipping, + train_decode_type=train_decode_type, + val_decode_type=val_decode_type, + test_decode_type=test_decode_type, + **constructive_policy_kw, + ) + + +class L2DPolicy4PPO(L2DPolicy): + def __init__( + self, + encoder=None, + decoder=None, + critic=None, + embed_dim: int = 64, + num_encoder_layers: int = 2, + env_name: str = "fjsp", + het_emb: bool = True, + scaling_factor: int = 1000, + init_embedding=None, + tanh_clipping: float = 10, + train_decode_type: str = "sampling", + val_decode_type: str = "greedy", + test_decode_type: str = "multistart_sampling", + **constructive_policy_kw, + ): + if init_embedding is None: + pass # TODO PPO specific init emb? + + super().__init__( + encoder=encoder, + decoder=decoder, + embed_dim=embed_dim, + num_encoder_layers=num_encoder_layers, + env_name=env_name, + het_emb=het_emb, + scaling_factor=scaling_factor, + init_embedding=init_embedding, + stepwise_encoding=True, + tanh_clipping=tanh_clipping, + train_decode_type=train_decode_type, + val_decode_type=val_decode_type, + test_decode_type=test_decode_type, + **constructive_policy_kw, + ) + + if critic is None: + if env_name == "fjsp" or het_emb: + input_dim = 2 * embed_dim + else: + input_dim = embed_dim + critic = MLP(input_dim, 1, num_neurons=[embed_dim] * 2) + + self.critic = critic + assert isinstance( + self.encoder, NoEncoder + ), "Define a feature extractor for decoder rather than an encoder in stepwise PPO" + + def evaluate(self, td): + # Encoder: get encoder output and initial embeddings from initial state + hidden, _ = self.decoder.feature_extractor(td) + # pool the embeddings for the critic + h_tuple = (hidden,) if isinstance(hidden, torch.Tensor) else hidden + pooled = tuple(map(lambda x: x.mean(dim=-2), h_tuple)) + # potentially cat multiple embeddings (pooled ops and machines) + h_pooled = torch.cat(pooled, dim=-1) + # pred value via the value head + value_pred = self.critic(h_pooled) + # pre decoder / actor hook + td, _, hidden = self.decoder.actor.pre_decoder_hook( + td, None, hidden, num_starts=0 + ) + logits, mask = self.decoder.actor(td, *hidden) + # get logprobs and entropy over logp distribution + logprobs = process_logits(logits, mask, tanh_clipping=self.tanh_clipping) + action_logprobs = gather_by_index(logprobs, td["action"], dim=1) + dist_entropys = Categorical(logprobs.exp()).entropy() + + return action_logprobs, value_pred, dist_entropys + + def act(self, td, env, phase: str = "train"): + logits, mask = self.decoder(td, hidden=None, num_starts=0) + logprobs = process_logits(logits, mask, tanh_clipping=self.tanh_clipping) + + # DRL-S, sampling actions following \pi + if phase == "train": + action_indexes = DecodingStrategy.sampling(logprobs) + td["logprobs"] = gather_by_index(logprobs, action_indexes, dim=1) + + # DRL-G, greedily picking actions with the maximum probability + else: + action_indexes = DecodingStrategy.greedy(logprobs) + + # memories.states.append(copy.deepcopy(state)) + td["action"] = action_indexes + + return td + + @torch.no_grad() + def generate(self, td, env=None, phase: str = "train", **kwargs) -> dict: + assert phase != "train", "dont use generate() in training mode" + with torch.no_grad(): + out = super().__call__(td, env, phase=phase, **kwargs) + return out diff --git a/rl4co/models/zoo/matnet/decoder.py b/rl4co/models/zoo/matnet/decoder.py index 616d38f9..ad8aef77 100644 --- a/rl4co/models/zoo/matnet/decoder.py +++ b/rl4co/models/zoo/matnet/decoder.py @@ -127,8 +127,8 @@ def __init__( self.cached_embs: PrecomputedCache = None # self.encoded_wait_op = nn.Parameter(torch.rand((1, 1, embed_dim))) - def _precompute_cache(self, embeddings: Tuple[Tensor], td: TensorDict = None): - self.cached_embs = super()._precompute_cache(embeddings, td) + def _precompute_cache(self, embeddings: Tuple[Tensor], **kwargs): + self.cached_embs = super()._precompute_cache(embeddings, **kwargs) def forward( self, @@ -141,7 +141,7 @@ def forward( batch_size = td.size(0) # TODO: we need to insert precompute cache inside the decoder - logits, mask = super().forward(self.cached_embs, td, num_starts) + logits, mask = super().forward(td, self.cached_embs, num_starts) logprobs = process_logits( logits, mask, diff --git a/rl4co/models/zoo/matnet/encoder.py b/rl4co/models/zoo/matnet/encoder.py index 87f8ffec..3ad52309 100644 --- a/rl4co/models/zoo/matnet/encoder.py +++ b/rl4co/models/zoo/matnet/encoder.py @@ -1,41 +1,28 @@ -import math - from typing import Optional import torch import torch.nn as nn import torch.nn.functional as F -from einops import rearrange - +from rl4co.models.nn.attention import MultiHeadCrossAttention from rl4co.models.nn.env_embeddings import env_init_embedding from rl4co.models.nn.ops import Normalization -class MatNetCrossMHA(nn.Module): +class MixedScoresSDPA(nn.Module): def __init__( self, - embed_dim: int, num_heads: int, - bias: bool = False, + num_scores: int = 1, mixer_hidden_dim: int = 16, mix1_init: float = (1 / 2) ** (1 / 2), mix2_init: float = (1 / 16) ** (1 / 2), ): super().__init__() - self.embed_dim = embed_dim self.num_heads = num_heads - assert self.embed_dim % num_heads == 0, "embed_dim must be divisible by num_heads" - self.head_dim = self.embed_dim // num_heads - - self.Wq = nn.Linear(embed_dim, embed_dim, bias=bias) - self.Wkv = nn.Linear(embed_dim, 2 * embed_dim, bias=bias) - - # Score mixer - # Taken from the official MatNet implementation - # https://github.com/yd-kwon/MatNet/blob/main/ATSP/ATSP_MatNet/ATSPModel_LIB.py#L72 + self.num_scores = num_scores mix_W1 = torch.torch.distributions.Uniform(low=-mix1_init, high=mix1_init).sample( - (num_heads, 2, mixer_hidden_dim) + (num_heads, self.num_scores + 1, mixer_hidden_dim) ) mix_b1 = torch.torch.distributions.Uniform(low=-mix1_init, high=mix1_init).sample( (num_heads, mixer_hidden_dim) @@ -52,38 +39,23 @@ def __init__( self.mix_W2 = nn.Parameter(mix_W2) self.mix_b2 = nn.Parameter(mix_b2) - self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias) - - def forward(self, q_input, kv_input, dmat): - """ - - Args: - q_input (Tensor): [b, m, d] - kv_input (Tensor): [b, n, d] - dmat (Tensor): [b, m, n] - - Returns: - Tensor: [b, m, d] - """ - - b, m, n = dmat.shape + def forward(self, q, k, v, attn_mask=None, dmat=None, dropout_p=0.0): + """Scaled Dot-Product Attention with MatNet Scores Mixer""" + assert dmat is not None + b, m, n = dmat.shape[:3] + dmat = dmat.reshape(b, m, n, self.num_scores) - q = rearrange( - self.Wq(q_input), "b m (h d) -> b h m d", h=self.num_heads - ) # [b, h, m, d] - k, v = rearrange( - self.Wkv(kv_input), "b n (two h d) -> two b h n d", two=2, h=self.num_heads - ).unbind( - dim=0 - ) # [b, h, n, d] - - scale = math.sqrt(q.size(-1)) # scale factor - attn_scores = torch.matmul(q, k.transpose(2, 3)) / scale # [b, h, m, n] - mix_attn_scores = torch.stack( - [attn_scores, dmat[:, None, :, :].expand(b, self.num_heads, m, n)], dim=-1 - ) # [b, h, m, n, 2] + # Calculate scaled dot product + attn_scores = torch.matmul(q, k.transpose(-2, -1)) / (k.size(-1) ** 0.5) + mix_attn_scores = torch.cat( + [ + attn_scores.unsqueeze(-1), + dmat[:, None, ...].expand(b, self.num_heads, m, n, self.num_scores), + ], + dim=-1, + ) # [b, h, m, n, num_scores+1] - mix_attn_scores = ( + attn_scores = ( ( torch.matmul( F.relu( @@ -98,9 +70,45 @@ def forward(self, q_input, kv_input, dmat): .squeeze(-1) ) # [b, h, m, n] - attn_probs = F.softmax(mix_attn_scores, dim=-1) - out = torch.matmul(attn_probs, v) - return self.out_proj(rearrange(out, "b h s d -> b s (h d)")) + # Apply the provided attention mask + if attn_mask is not None: + if attn_mask.dtype == torch.bool: + attn_mask[~attn_mask.any(-1)] = True + attn_scores.masked_fill_(~attn_mask, float("-inf")) + else: + attn_scores += attn_mask + + # Softmax to get attention weights + attn_weights = F.softmax(attn_scores, dim=-1) + + # Apply dropout + if dropout_p > 0.0: + attn_weights = F.dropout(attn_weights, p=dropout_p) + + # Compute the weighted sum of values + return torch.matmul(attn_weights, v) + + +class MatNetCrossMHA(MultiHeadCrossAttention): + def __init__( + self, + embed_dim: int, + num_heads: int, + bias: bool = False, + mixer_hidden_dim: int = 16, + mix1_init: float = (1 / 2) ** (1 / 2), + mix2_init: float = (1 / 16) ** (1 / 2), + ): + attn_fn = MixedScoresSDPA( + num_heads=num_heads, + mixer_hidden_dim=mixer_hidden_dim, + mix1_init=mix1_init, + mix2_init=mix2_init, + ) + + super().__init__( + embed_dim=embed_dim, num_heads=num_heads, bias=bias, sdpa_fn=attn_fn + ) class MatNetMHA(nn.Module): @@ -109,7 +117,7 @@ def __init__(self, embed_dim: int, num_heads: int, bias: bool = False): self.row_encoding_block = MatNetCrossMHA(embed_dim, num_heads, bias) self.col_encoding_block = MatNetCrossMHA(embed_dim, num_heads, bias) - def forward(self, row_emb, col_emb, dmat): + def forward(self, row_emb, col_emb, dmat, attn_mask=None): """ Args: row_emb (Tensor): [b, m, d] @@ -120,10 +128,15 @@ def forward(self, row_emb, col_emb, dmat): Updated row_emb (Tensor): [b, m, d] Updated col_emb (Tensor): [b, n, d] """ - - updated_row_emb = self.row_encoding_block(row_emb, col_emb, dmat) + updated_row_emb = self.row_encoding_block( + row_emb, col_emb, dmat=dmat, cross_attn_mask=attn_mask + ) + attn_mask_t = attn_mask.transpose(-2, -1) if attn_mask is not None else None updated_col_emb = self.col_encoding_block( - col_emb, row_emb, dmat.transpose(-2, -1) + col_emb, + row_emb, + dmat=dmat.transpose(-2, -1), + cross_attn_mask=attn_mask_t, ) return updated_row_emb, updated_col_emb @@ -164,7 +177,7 @@ def __init__( } ) - def forward(self, row_emb, col_emb, dmat): + def forward(self, row_emb, col_emb, dmat, attn_mask=None): """ Args: row_emb (Tensor): [b, m, d] @@ -176,7 +189,7 @@ def forward(self, row_emb, col_emb, dmat): Updated col_emb (Tensor): [b, n, d] """ - row_emb_out, col_emb_out = self.MHA(row_emb, col_emb, dmat) + row_emb_out, col_emb_out = self.MHA(row_emb, col_emb, dmat, attn_mask) row_emb_out = self.F_a["norm1"](row_emb + row_emb_out) row_emb_out = self.F_a["norm2"](row_emb_out + self.F_a["ffn"](row_emb_out)) @@ -210,7 +223,7 @@ def __init__( ] ) - def forward(self, row_emb, col_emb, dmat): + def forward(self, row_emb, col_emb, dmat, attn_mask=None): """ Args: row_emb (Tensor): [b, m, d] @@ -223,7 +236,7 @@ def forward(self, row_emb, col_emb, dmat): """ for layer in self.layers: - row_emb, col_emb = layer(row_emb, col_emb, dmat) + row_emb, col_emb = layer(row_emb, col_emb, dmat, attn_mask) return row_emb, col_emb @@ -236,8 +249,9 @@ def __init__( normalization: str = "instance", feedforward_hidden: int = 512, init_embedding: nn.Module = None, - init_embedding_kwargs: dict = None, + init_embedding_kwargs: dict = {}, bias: bool = False, + mask_non_neighbors: bool = False, ): super().__init__() @@ -255,10 +269,16 @@ def __init__( feedforward_hidden=feedforward_hidden, bias=bias, ) + self.mask_non_neighbors = mask_non_neighbors - def forward(self, td): + def forward(self, td, attn_mask: torch.Tensor = None): row_emb, col_emb, dmat = self.init_embedding(td) - row_emb, col_emb = self.net(row_emb, col_emb, dmat) + + if self.mask_non_neighbors and attn_mask is None: + # attn_mask (keep 1s discard 0s) to only attend on neighborhood + attn_mask = dmat.ne(0) + + row_emb, col_emb = self.net(row_emb, col_emb, dmat, attn_mask) embedding = (row_emb, col_emb) init_embedding = None diff --git a/rl4co/models/zoo/matnet/matnet_w_sa.py b/rl4co/models/zoo/matnet/matnet_w_sa.py new file mode 100644 index 00000000..cf06056f --- /dev/null +++ b/rl4co/models/zoo/matnet/matnet_w_sa.py @@ -0,0 +1,202 @@ +import math + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from einops import rearrange + +from rl4co.models.nn.attention import MultiHeadAttention +from rl4co.models.nn.env_embeddings import env_init_embedding +from rl4co.models.nn.ops import Normalization, TransformerFFN + + +def apply_weights_and_combine(dots, v, tanh_clipping=0): + # scale to avoid numerical underflow + logits = dots / dots.std() + if tanh_clipping > 0: + # tanh clipping to avoid explosions + logits = torch.tanh(logits) * tanh_clipping + # shape: (batch, num_heads, row_cnt, col_cnt) + weights = nn.Softmax(dim=-1)(logits) + weights = weights.nan_to_num(0) + # shape: (batch, num_heads, row_cnt, qkv_dim) + out = torch.matmul(weights, v) + # shape: (batch, row_cnt, num_heads, qkv_dim) + out = rearrange(out, "b h s d -> b s (h d)") + return out + + +class MixedScoreFF(nn.Module): + def __init__(self, num_heads, ms_hidden_dim: int = 32, bias: bool = False) -> None: + super().__init__() + + self.lin1 = nn.Linear(2 * num_heads, num_heads * ms_hidden_dim, bias=bias) + self.lin2 = nn.Linear(num_heads * ms_hidden_dim, num_heads, bias=bias) + + def forward(self, dot_product_score, cost_mat_score): + # dot_product_score shape: (batch, head_num, row_cnt, col_cnt) + # cost_mat_score shape: (batch, head_num, row_cnt, col_cnt) + # shape: (batch, head_num, row_cnt, col_cnt, 2) + two_scores = torch.stack((dot_product_score, cost_mat_score), dim=-1) + two_scores = rearrange(two_scores, "b h r c s -> b r c (h s)") + # shape: (batch, row_cnt, col_cnt, 2 * num_heads) + ms1 = self.lin1(two_scores) + ms1_activated = F.relu(ms1) + # shape: (batch, row_cnt, col_cnt, num_heads) + ms2 = self.lin2(ms1_activated) + # shape: (batch, row_cnt, head_num, col_cnt) + mixed_scores = rearrange(ms2, "b r c h -> b h r c") + + return mixed_scores + + +class EfficientMixedScoreMultiHeadAttention(nn.Module): + def __init__(self, embed_dim: int, num_heads: int, bias: bool = False): + super().__init__() + + qkv_dim = embed_dim // num_heads + + self.num_heads = num_heads + self.qkv_dim = qkv_dim + self.norm_factor = 1 / math.sqrt(qkv_dim) + + self.Wqv1 = nn.Linear(embed_dim, 2 * embed_dim, bias=bias) + self.Wkv2 = nn.Linear(embed_dim, 2 * embed_dim, bias=bias) + + # self.init_parameters() + self.mixed_scores_layer = MixedScoreFF(num_heads, qkv_dim, bias) + + self.out_proj1 = nn.Linear(embed_dim, embed_dim, bias=bias) + self.out_proj2 = nn.Linear(embed_dim, embed_dim, bias=bias) + + def forward(self, x1, x2, attn_mask=None, cost_mat=None): + batch_size = x1.size(0) + row_cnt = x1.size(-2) + col_cnt = x2.size(-2) + + # Project query, key, value + q, v1 = rearrange( + self.Wqv1(x1), "b s (two h d) -> two b h s d", two=2, h=self.num_heads + ).unbind(dim=0) + + # Project query, key, value + k, v2 = rearrange( + self.Wqv1(x2), "b s (two h d) -> two b h s d", two=2, h=self.num_heads + ).unbind(dim=0) + + # shape: (batch, num_heads, row_cnt, col_cnt) + dot = self.norm_factor * torch.matmul(q, k.transpose(-2, -1)) + + if cost_mat is not None: + # shape: (batch, num_heads, row_cnt, col_cnt) + cost_mat_score = cost_mat[:, None, :, :].expand_as(dot) + dot = self.mixed_scores_layer(dot, cost_mat_score) + + if attn_mask is not None: + attn_mask = attn_mask.view(batch_size, 1, row_cnt, col_cnt).expand_as(dot) + dot.masked_fill_(~attn_mask, float("-inf")) + + h1 = self.out_proj1(apply_weights_and_combine(dot, v2)) + h2 = self.out_proj2(apply_weights_and_combine(dot.transpose(-2, -1), v1)) + + return h1, h2 + + +class EncoderLayer(nn.Module): + def __init__( + self, + embed_dim: int, + num_heads: int = 8, + feedforward_hidden: int = 512, + normalization: str = "batch", + bias: bool = False, + ): + super().__init__() + + self.op_attn = MultiHeadAttention(embed_dim, num_heads, bias=bias) + self.ma_attn = MultiHeadAttention(embed_dim, num_heads, bias=bias) + self.cross_attn = EfficientMixedScoreMultiHeadAttention( + embed_dim, num_heads, bias=bias + ) + + self.op_ffn = TransformerFFN(embed_dim, feedforward_hidden, normalization) + self.ma_ffn = TransformerFFN(embed_dim, feedforward_hidden, normalization) + + self.op_norm = Normalization(embed_dim, normalization) + self.ma_norm = Normalization(embed_dim, normalization) + + def forward( + self, op_in, ma_in, cost_mat, op_mask=None, ma_mask=None, cross_mask=None + ): + op_cross_out, ma_cross_out = self.cross_attn( + op_in, ma_in, attn_mask=cross_mask, cost_mat=cost_mat + ) + op_cross_out = self.op_norm(op_cross_out + op_in) + ma_cross_out = self.ma_norm(ma_cross_out + ma_in) + + # (bs, num_jobs, ops_per_job, d) + op_self_out = self.op_attn(op_cross_out, attn_mask=op_mask) + # (bs, num_ma, d) + ma_self_out = self.ma_attn(ma_cross_out, attn_mask=ma_mask) + + op_out = self.op_ffn(op_cross_out, op_self_out) + ma_out = self.ma_ffn(ma_cross_out, ma_self_out) + + return op_out, ma_out + + +class Encoder(nn.Module): + def __init__( + self, + embed_dim: int = 256, + num_heads: int = 16, + num_layers: int = 5, + normalization: str = "batch", + feedforward_hidden: int = 512, + init_embedding: nn.Module = None, + init_embedding_kwargs: dict = {}, + bias: bool = False, + ): + super().__init__() + self.d_model = embed_dim + + if init_embedding is None: + init_embedding = env_init_embedding( + "matnet", {"embed_dim": embed_dim, **init_embedding_kwargs} + ) + self.init_embedding = init_embedding + self.layers = nn.ModuleList( + [ + EncoderLayer( + embed_dim=embed_dim, + num_heads=num_heads, + feedforward_hidden=feedforward_hidden, + normalization=normalization, + bias=bias, + ) + for _ in range(num_layers) + ] + ) + + def forward(self, td, attn_mask: torch.Tensor = None): + # [BS, num_machines, emb], [BS, num_operations, emb] + ops_embed, ma_embed, edge_feat = self.init_embedding(td) + try: + # mask padded ops; shape=(bs, ops) + ops_attn_mask = ~td["pad_mask"] + except KeyError: + ops_attn_mask = None + # padded ops should also be masked in cross attention; shape=(bs, ops, ma) + # cross_mask = ops_attn_mask.unsqueeze(-1).expand(-1, -1, ma_embed.size(1)) + for layer in self.layers: + ops_embed, ma_embed = layer( + ops_embed, + ma_embed, + cost_mat=edge_feat, + op_mask=ops_attn_mask, # mask padded operations in attention + ma_mask=None, # no padding for machines + cross_mask=None, + ) + embedding = (ops_embed, ma_embed) + return embedding, None diff --git a/rl4co/models/zoo/matnet/policy.py b/rl4co/models/zoo/matnet/policy.py index 24212310..0c2af426 100644 --- a/rl4co/models/zoo/matnet/policy.py +++ b/rl4co/models/zoo/matnet/policy.py @@ -141,7 +141,7 @@ def pre_forward(self, td: TensorDict, env: FFSPEnv, num_starts: int): encoder = self.encoders[stage_idx] embeddings, _ = encoder(td) decoder = self.decoders[stage_idx] - decoder._precompute_cache(embeddings, td) + decoder._precompute_cache(embeddings) if num_starts > 1: # repeat num_start times diff --git a/rl4co/tasks/train.py b/rl4co/tasks/train.py index 6826382d..b1d104b4 100644 --- a/rl4co/tasks/train.py +++ b/rl4co/tasks/train.py @@ -47,7 +47,7 @@ def run(cfg: DictConfig) -> Tuple[dict, dict]: callbacks: List[Callback] = utils.instantiate_callbacks(cfg.get("callbacks")) log.info("Instantiating loggers...") - logger: List[Logger] = utils.instantiate_loggers(cfg.get("logger")) + logger: List[Logger] = utils.instantiate_loggers(cfg.get("logger"), model) log.info("Instantiating trainer...") trainer: RL4COTrainer = hydra.utils.instantiate( diff --git a/rl4co/utils/instantiators.py b/rl4co/utils/instantiators.py index e3b25183..9f4cdaf4 100644 --- a/rl4co/utils/instantiators.py +++ b/rl4co/utils/instantiators.py @@ -31,14 +31,14 @@ def instantiate_callbacks(callbacks_cfg: DictConfig) -> List[Callback]: return callbacks -def instantiate_loggers(logger_cfg: DictConfig) -> List[Logger]: +def instantiate_loggers(logger_cfg: DictConfig, model) -> List[Logger]: """Instantiates loggers from config.""" - logger: List[Logger] = [] + logger_list: List[Logger] = [] if not logger_cfg: log.warning("No logger configs found! Skipping...") - return logger + return logger_list if not isinstance(logger_cfg, DictConfig): raise TypeError("Logger config must be a DictConfig!") @@ -46,6 +46,16 @@ def instantiate_loggers(logger_cfg: DictConfig) -> List[Logger]: for _, lg_conf in logger_cfg.items(): if isinstance(lg_conf, DictConfig) and "_target_" in lg_conf: log.info(f"Instantiating logger <{lg_conf._target_}>") - logger.append(hydra.utils.instantiate(lg_conf)) - - return logger + if hasattr(lg_conf, "log_gradients"): + log_gradients = lg_conf.get("log_gradients", False) + # manually remove parameter, since pop doesnt work on DictConfig + del lg_conf.log_gradients + else: + log_gradients = False + logger = hydra.utils.instantiate(lg_conf) + if hasattr(logger, "watch") and log_gradients: + # make use of wandb gradient statistics logger + logger.watch(model, log_graph=False) + logger_list.append(logger) + + return logger_list diff --git a/rl4co/utils/ops.py b/rl4co/utils/ops.py index ce32aeef..86dc2a1e 100644 --- a/rl4co/utils/ops.py +++ b/rl4co/utils/ops.py @@ -73,7 +73,8 @@ def gather_by_index(src, idx, dim=1, squeeze=True): expanded_shape = list(src.shape) expanded_shape[dim] = -1 idx = idx.view(idx.shape + (1,) * (src.dim() - idx.dim())).expand(expanded_shape) - return src.gather(dim, idx).squeeze() if squeeze else src.gather(dim, idx) + squeeze = idx.size(dim) == 1 and squeeze + return src.gather(dim, idx).squeeze(dim) if squeeze else src.gather(dim, idx) def unbatchify_and_gather(x: Tensor, idx: Tensor, n: int): @@ -151,8 +152,8 @@ def select_start_nodes(td, env, num_starts): torch.arange(num_starts, device=td.device).repeat_interleave(td.shape[0]) % num_loc ) - elif env.name == "fjsp": - raise NotImplementedError("Multistart not yet supported for FJSP") + elif env.name in ["jssp", "fjsp"]: + raise NotImplementedError("Multistart not yet supported for FJSP/JSSP") else: # Environments with depot: we do not select the depot as a start node selected = ( @@ -221,6 +222,26 @@ def get_full_graph_edge_index(num_node: int, self_loop=False) -> Tensor: return edge_index +def adj_to_pyg_edge_index(adj: Tensor) -> Tensor: + """transforms an adjacency matrix (boolean) to a Tensor with the respective edge + indices (in the format required by the pytorch geometric module). + + :param Tensor adj: shape=(bs, num_nodes, num_nodes) + :return Tensor: shape=(2, num_edges) + """ + assert adj.size(1) == adj.size(2), "only symmetric adjacency matrices are supported" + num_nodes = adj.size(1) + # (num_edges, 3) + edge_idx = adj.nonzero() + batch_idx = edge_idx[:, 0] * num_nodes + # PyG expects a "single, flat graph", in which the graphs of the batch are not connected. + # Therefore, add the batch_idx to edge_idx to have unique indices + flat_edge_idx = edge_idx[:, 1:] + batch_idx[:, None] + # (2, num_edges) + flat_edge_idx = torch.permute(flat_edge_idx, (1, 0)) + return flat_edge_idx + + def sample_n_random_actions(td: TensorDict, n: int): """Helper function to sample n random actions from available actions. If number of valid actions is less then n, we sample with replacement from the diff --git a/tests/test_envs.py b/tests/test_envs.py index bd8d416b..775a46be 100644 --- a/tests/test_envs.py +++ b/tests/test_envs.py @@ -4,6 +4,8 @@ import pytest import torch +from tensordict import TensorDict + from rl4co.envs import ( ATSPEnv, CVRPEnv, @@ -11,6 +13,7 @@ DPPEnv, FFSPEnv, FJSPEnv, + JSSPEnv, MDCPDPEnv, MDPPEnv, MTSPEnv, @@ -46,7 +49,6 @@ MTSPEnv, ATSPEnv, MDCPDPEnv, - FJSPEnv, ], ) def test_routing(env_cls, batch_size=2, size=20): @@ -89,12 +91,12 @@ def test_eda(env_cls, batch_size=2, max_decaps=5): assert reward.shape == (batch_size,) -@pytest.mark.parametrize("env_cls", [FFSPEnv]) -def test_scheduling(env_cls, batch_size=2): +@pytest.mark.parametrize("env_cls", [FFSPEnv, FJSPEnv, JSSPEnv]) +@pytest.mark.parametrize("mask_no_ops", [True, False]) +def test_scheduling(env_cls, mask_no_ops, batch_size=2): env = env_cls() - td = env.reset(batch_size=[batch_size]) - td["action"] = torch.tensor([1, 1]) - td = env._step(td) + reward, td, actions = rollout(env, env.reset(batch_size=[batch_size]), random_policy) + assert reward.shape == (batch_size,) @pytest.mark.parametrize("env_cls", [SMTWTPEnv]) @@ -102,3 +104,45 @@ def test_smtwtp(env_cls, batch_size=2): env = env_cls(num_job=4) reward, td, actions = rollout(env, env.reset(batch_size=[batch_size]), random_policy) assert reward.shape == (batch_size,) + + +@pytest.mark.parametrize("env_cls", [JSSPEnv]) +def test_jssp_lb(env_cls): + env = env_cls(generator_params={"num_jobs": 2, "num_machines": 2}) + td = TensorDict( + { + "proc_times": torch.tensor( + [[[1, 0, 0, 4], [0, 2, 3, 0]]], dtype=torch.float32 + ), + "start_op_per_job": torch.tensor([[0, 2]], dtype=torch.long), + "end_op_per_job": torch.tensor([[1, 3]], dtype=torch.long), + "pad_mask": torch.tensor([[0, 0, 0, 0]], dtype=torch.bool), + }, + batch_size=[1], + ) + + td = env.reset(td) + + actions = [0, 1, 1] + for action in actions: + # NOTE add 1 to account for dummy action (waiting) + td.set("action", torch.tensor([action + 1], dtype=torch.long)) + td = env.step(td)["next"] + + lb_expected = torch.tensor([[1, 5, 3, 7]], dtype=torch.float32) + assert torch.allclose(td["lbs"], lb_expected) + + +def test_scheduling_dataloader(): + from tempfile import TemporaryDirectory + + from rl4co.envs.scheduling.fjsp.parser import write + + write_env = FJSPEnv() + + td = write_env.reset(batch_size=[2]) + with TemporaryDirectory() as tmpdirname: + write(tmpdirname, td) + read_env = FJSPEnv(generator_params={"file_path": tmpdirname}) + td = read_env.reset(batch_size=2) + assert td.size(0) == 2 diff --git a/tests/test_training.py b/tests/test_training.py index 89513ce4..1f249e55 100644 --- a/tests/test_training.py +++ b/tests/test_training.py @@ -3,7 +3,7 @@ import pytest -from rl4co.envs import ATSPEnv, PDPEnv, PDPRuinRepairEnv, TSPEnv +from rl4co.envs import ATSPEnv, FJSPEnv, JSSPEnv, PDPEnv, PDPRuinRepairEnv, TSPEnv from rl4co.models.rl import A2C, PPO, REINFORCE from rl4co.models.zoo import ( MDAM, @@ -14,6 +14,7 @@ EASEmb, EASLay, HeterogeneousAttentionModel, + L2DPPOModel, MatNet, NARGNNPolicy, SymNCO, @@ -177,3 +178,19 @@ def test_N2S(): ) trainer.fit(model) trainer.test(model) + + +@pytest.mark.parametrize("env_cls", [FJSPEnv, JSSPEnv]) +def test_l2d_ppo(env_cls): + env = env_cls(stepwise_reward=True, _torchrl_mode=True) + model = L2DPPOModel( + env, train_data_size=10, val_data_size=10, test_data_size=10, buffer_size=1000 + ) + trainer = RL4COTrainer( + max_epochs=1, + gradient_clip_val=0.05, + devices=1, + accelerator=accelerator, + ) + trainer.fit(model) + trainer.test(model)