```python
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.cpp_extension import load_inline


_cpp_source = r"""
#include <torch/extension.h>

torch::Tensor transform_weight(torch::Tensor weight);
torch::Tensor expand_output(
    torch::Tensor compact,
    c10::optional<torch::Tensor> bias);
"""

_cuda_source = r"""
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <c10/cuda/CUDAGuard.h>
#include <c10/cuda/CUDAException.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <algorithm>

template <typename scalar_t>
__global__ void transform_weight_kernel(
    const scalar_t* __restrict__ src,
    scalar_t* __restrict__ dst,
    int64_t count,
    int cin,
    int cout)
{
    for (int64_t index = int64_t(blockIdx.x) * blockDim.x + threadIdx.x;
         index < count;
         index += int64_t(blockDim.x) * gridDim.x) {
        const int k = index % 27;
        const int ic = (index / 27) % cin;
        const int oc = index / (int64_t(27) * cin);
        dst[index] = src[(int64_t(ic) * cout + oc) * 27 + 26 - k];
    }
}

template <typename scalar_t, bool HAS_BIAS>
__global__ void expand_output_kernel(
    const scalar_t* __restrict__ compact,
    const scalar_t* __restrict__ bias,
    scalar_t* __restrict__ output,
    int64_t count,
    int channels,
    int depth,
    int height,
    int width,
    int out_depth,
    int out_height,
    int out_width)
{
    for (int64_t index = int64_t(blockIdx.x) * blockDim.x + threadIdx.x;
         index < count;
         index += int64_t(blockDim.x) * gridDim.x) {
        int64_t q = index;
        const int ow = q % out_width;
        q /= out_width;
        const int oh = q % out_height;
        q /= out_height;
        const int od = q % out_depth;
        const int64_t nc = q / out_depth;

        scalar_t value = scalar_t(0);
        if ((ow & 1) && (oh & 1) && (od & 1)) {
            const int64_t source =
                ((nc * depth + od / 2) * height + oh / 2) * width + ow / 2;
            value = compact[source];
        }
        if (HAS_BIAS) {
            value = value + bias[nc % channels];
        }
        output[index] = value;
    }
}

torch::Tensor transform_weight(torch::Tensor weight)
{
    TORCH_CHECK(weight.is_cuda(), "weight must be CUDA");
    TORCH_CHECK(
        weight.dim() == 5 &&
        weight.size(2) == 3 &&
        weight.size(3) == 3 &&
        weight.size(4) == 3,
        "expected a 3x3x3 kernel");

    const c10::cuda::CUDAGuard guard(weight.device());
    weight = weight.contiguous();

    const int cin = weight.size(0);
    const int cout = weight.size(1);
    auto result = torch::empty({cout, cin, 3, 3, 3}, weight.options());
    const int64_t count = weight.numel();
    const int blocks = static_cast<int>(
        std::min<int64_t>((count + 255) / 256, 65535));
    const cudaStream_t stream = at::cuda::getCurrentCUDAStream();

    AT_DISPATCH_FLOATING_TYPES_AND2(
        at::ScalarType::Half, at::ScalarType::BFloat16,
        weight.scalar_type(), "transform_weight", [&] {
            transform_weight_kernel<scalar_t><<<blocks, 256, 0, stream>>>(
                weight.data_ptr<scalar_t>(),
                result.data_ptr<scalar_t>(),
                count, cin, cout);
        });
    C10_CUDA_KERNEL_LAUNCH_CHECK();
    return result;
}

torch::Tensor expand_output(
    torch::Tensor compact,
    c10::optional<torch::Tensor> bias)
{
    TORCH_CHECK(compact.is_cuda(), "compact must be CUDA");
    const c10::cuda::CUDAGuard guard(compact.device());
    compact = compact.contiguous();

    const int64_t batch = compact.size(0);
    const int channels = compact.size(1);
    const int depth = compact.size(2);
    const int height = compact.size(3);
    const int width = compact.size(4);
    const int out_depth = 2 * depth + 1;
    const int out_height = 2 * height + 1;
    const int out_width = 2 * width + 1;

    const bool has_bias = bias.has_value() && bias->defined();
    torch::Tensor contiguous_bias;
    if (has_bias) {
        TORCH_CHECK(bias->device() == compact.device(), "bias device mismatch");
        TORCH_CHECK(
            bias->scalar_type() == compact.scalar_type(),
            "bias dtype mismatch");
        contiguous_bias = bias->contiguous();
    }

    auto output = torch::empty(
        {batch, channels, out_depth, out_height, out_width},
        compact.options());

    const int64_t count = output.numel();
    if (count == 0) {
        return output;
    }

    const int blocks = static_cast<int>(
        std::min<int64_t>((count + 255) / 256, 65535));
    const cudaStream_t stream = at::cuda::getCurrentCUDAStream();

    AT_DISPATCH_FLOATING_TYPES_AND2(
        at::ScalarType::Half, at::ScalarType::BFloat16,
        compact.scalar_type(), "expand_output", [&] {
            const scalar_t* bias_ptr =
                has_bias ? contiguous_bias.data_ptr<scalar_t>() : nullptr;

            if (has_bias) {
                expand_output_kernel<scalar_t, true>
                    <<<blocks, 256, 0, stream>>>(
                        compact.data_ptr<scalar_t>(), bias_ptr,
                        output.data_ptr<scalar_t>(), count,
                        channels, depth, height, width,
                        out_depth, out_height, out_width);
            } else {
                expand_output_kernel<scalar_t, false>
                    <<<blocks, 256, 0, stream>>>(
                        compact.data_ptr<scalar_t>(), nullptr,
                        output.data_ptr<scalar_t>(), count,
                        channels, depth, height, width,
                        out_depth, out_height, out_width);
            }
        });
    C10_CUDA_KERNEL_LAUNCH_CHECK();
    return output;
}
"""

_extension = load_inline(
    name="compact_conv_transpose3d_cuda_v1",
    cpp_sources=_cpp_source,
    cuda_sources=_cuda_source,
    functions=["transform_weight", "expand_output"],
    extra_cflags=["-O3"],
    extra_cuda_cflags=["-O3"],
    verbose=False,
)


class ModelNew(nn.Module):
    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        kernel_size: int,
        stride: int = 1,
        padding: int = 0,
        dilation: int = 1,
        bias: bool = False,
    ):
        super().__init__()
        self.conv_transpose3d = nn.ConvTranspose3d(
            in_channels,
            out_channels,
            kernel_size=(kernel_size, kernel_size, kernel_size),
            stride=stride,
            padding=padding,
            dilation=dilation,
            bias=bias,
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        conv = self.conv_transpose3d
        supported = (
            x.is_cuda
            and x.ndim == 5
            and x.dtype in (torch.float32, torch.float64, torch.float16, torch.bfloat16)
            and conv.kernel_size == (3, 3, 3)
            and conv.stride == (2, 2, 2)
            and conv.padding == (1, 1, 1)
            and conv.dilation == (2, 2, 2)
            and conv.output_padding == (0, 0, 0)
            and conv.groups == 1
        )

        if not supported:
            return conv(x)

        # Every contributing output coordinate is odd in all three dimensions.
        # Compute just those coordinates using a dense, undilated convolution.
        weight = _extension.transform_weight(conv.weight)
        compact = F.conv3d(x, weight, bias=None, stride=1, padding=1)

        bias = conv.bias
        if bias is not None and bias.dtype != compact.dtype:
            bias = bias.to(dtype=compact.dtype)
        return _extension.expand_output(compact, bias)
```