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


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

torch::Tensor pooled_transpose_cuda(
    torch::Tensor x,
    torch::Tensor weight,
    torch::Tensor conv_bias,
    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_runtime.h>
#include <cstdint>

constexpr int THREADS = 256;
constexpr int TILE = 4096;

__device__ __forceinline__ float warp_sum(float value) {
    #pragma unroll
    for (int offset = 16; offset > 0; offset >>= 1)
        value += __shfl_down_sync(0xffffffff, value, offset);
    return value;
}

__device__ __forceinline__ float warp_max(float value) {
    #pragma unroll
    for (int offset = 16; offset > 0; offset >>= 1)
        value = fmaxf(
            value, __shfl_down_sync(0xffffffff, value, offset));
    return value;
}

template<bool VECTORIZED>
__global__ void spatial_partials(
    const float* __restrict__ x,
    float* __restrict__ partials,
    int64_t spatial,
    int chunks)
{
    __shared__ float warp_results[8];

    const int tid = threadIdx.x;
    const int chunk = blockIdx.x % chunks;
    const int64_t row = blockIdx.x / chunks;
    const float* input = x + row * spatial;
    float sum = 0.0f;

    if (VECTORIZED) {
        const float4* input4 = reinterpret_cast<const float4*>(input);
        const int64_t start = int64_t(chunk) * (TILE / 4);

        #pragma unroll
        for (int i = tid; i < TILE / 4; i += THREADS) {
            const int64_t index = start + i;
            if (index < spatial / 4) {
                const float4 v = input4[index];
                sum += (v.x + v.y) + (v.z + v.w);
            }
        }
    } else {
        const int64_t start = int64_t(chunk) * TILE;

        #pragma unroll
        for (int i = tid; i < TILE; i += THREADS) {
            const int64_t index = start + i;
            if (index < spatial)
                sum += input[index];
        }
    }

    sum = warp_sum(sum);
    if ((tid & 31) == 0)
        warp_results[tid >> 5] = sum;
    __syncthreads();

    if (tid < 32) {
        sum = tid < 8 ? warp_results[tid] : 0.0f;
        sum = warp_sum(sum);
        if (tid == 0)
            partials[blockIdx.x] = sum;
    }
}

__global__ void finish_pooled_transpose(
    const float* __restrict__ partials,
    const float* __restrict__ weight,
    const float* __restrict__ conv_bias,
    const float* __restrict__ bias,
    float* __restrict__ output,
    int in_channels,
    int out_channels,
    int kernel_area,
    int chunks,
    float inverse_output_area)
{
    extern __shared__ float shared[];
    float* pooled = shared;
    float* logits = pooled + in_channels;
    float* scratch = logits + out_channels;

    const int tid = threadIdx.x;
    const int batch = blockIdx.x;

    for (int c = tid; c < in_channels; c += THREADS) {
        const float* p = partials
            + (int64_t(batch) * in_channels + c) * chunks;
        float sum = 0.0f;
        for (int j = 0; j < chunks; ++j)
            sum += p[j];
        pooled[c] = sum * inverse_output_area;
    }
    __syncthreads();

    // With stride one and no padding, every input element contributes
    // every kernel coefficient to the spatial sum of the output.
    float local_max = -CUDART_INF_F;
    for (int o = tid; o < out_channels; o += THREADS) {
        float value = 0.0f;
        for (int c = 0; c < in_channels; ++c) {
            const float* w = weight
                + (int64_t(c) * out_channels + o) * kernel_area;
            float weight_sum = 0.0f;
            for (int k = 0; k < kernel_area; ++k)
                weight_sum += w[k];
            value = fmaf(pooled[c], weight_sum, value);
        }
        value = (value + conv_bias[o]) + bias[o];
        logits[o] = value;
        local_max = fmaxf(local_max, value);
    }

    local_max = warp_max(local_max);
    if ((tid & 31) == 0)
        scratch[tid >> 5] = local_max;
    __syncthreads();

    if (tid < 32) {
        float value = tid < 8 ? scratch[tid] : -CUDART_INF_F;
        value = warp_max(value);
        if (tid == 0)
            scratch[8] = value;
    }
    __syncthreads();

    const float maximum = scratch[8];
    float local_sum = 0.0f;
    for (int o = tid; o < out_channels; o += THREADS)
        local_sum += expf(logits[o] - maximum);

    local_sum = warp_sum(local_sum);
    if ((tid & 31) == 0)
        scratch[tid >> 5] = local_sum;
    __syncthreads();

    if (tid < 32) {
        float value = tid < 8 ? scratch[tid] : 0.0f;
        value = warp_sum(value);
        if (tid == 0)
            output[batch] = (maximum + logf(value)) * 10.0f;
    }
}

torch::Tensor pooled_transpose_cuda(
    torch::Tensor x,
    torch::Tensor weight,
    torch::Tensor conv_bias,
    torch::Tensor bias)
{
    const c10::cuda::CUDAGuard guard(x.device());

    TORCH_CHECK(x.is_cuda() && x.scalar_type() == at::kFloat);
    TORCH_CHECK(x.is_contiguous() && weight.is_contiguous());
    TORCH_CHECK(conv_bias.is_contiguous() && bias.is_contiguous());
    TORCH_CHECK(weight.device() == x.device()
                && conv_bias.device() == x.device()
                && bias.device() == x.device());
    TORCH_CHECK(weight.scalar_type() == at::kFloat
                && conv_bias.scalar_type() == at::kFloat
                && bias.scalar_type() == at::kFloat);
    TORCH_CHECK(x.dim() == 4 && weight.dim() == 4);
    TORCH_CHECK(x.size(1) == weight.size(0));

    const int64_t batch = x.size(0);
    const int in_channels = weight.size(0);
    const int out_channels = weight.size(1);
    const int64_t spatial = x.size(2) * x.size(3);
    TORCH_CHECK(spatial > 0);
    TORCH_CHECK(conv_bias.numel() == out_channels
                && bias.numel() == out_channels);

    const int kernel_area = weight.size(2) * weight.size(3);
    const int chunks = (spatial + TILE - 1) / TILE;
    const int64_t output_area =
        (x.size(2) + weight.size(2) - 1) *
        (x.size(3) + weight.size(3) - 1);

    auto output = torch::empty({batch, 1}, x.options());
    if (batch == 0)
        return output;

    auto partials = torch::empty(
        {batch, in_channels, chunks}, x.options());

    const int64_t blocks = batch * in_channels * chunks;
    TORCH_CHECK(blocks <= 2147483647LL);
    const size_t shared_bytes =
        size_t(in_channels + out_channels + 9) * sizeof(float);
    TORCH_CHECK(shared_bytes <= 48 * 1024);

    cudaStream_t stream = at::cuda::getCurrentCUDAStream();

    const bool vectorized =
        spatial % 4 == 0 &&
        (reinterpret_cast<uintptr_t>(x.data_ptr<float>()) % 16 == 0);

    if (vectorized) {
        spatial_partials<true><<<blocks, THREADS, 0, stream>>>(
            x.data_ptr<float>(), partials.data_ptr<float>(),
            spatial, chunks);
    } else {
        spatial_partials<false><<<blocks, THREADS, 0, stream>>>(
            x.data_ptr<float>(), partials.data_ptr<float>(),
            spatial, chunks);
    }
    C10_CUDA_KERNEL_LAUNCH_CHECK();

    finish_pooled_transpose<<<batch, THREADS, shared_bytes, stream>>>(
        partials.data_ptr<float>(),
        weight.data_ptr<float>(),
        conv_bias.data_ptr<float>(),
        bias.data_ptr<float>(),
        output.data_ptr<float>(),
        in_channels, out_channels, kernel_area, chunks,
        1.0f / static_cast<float>(output_area));
    C10_CUDA_KERNEL_LAUNCH_CHECK();

    return output;
}
"""

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


class ModelNew(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, bias_shape):
        super().__init__()
        self.conv_transpose = nn.ConvTranspose2d(
            in_channels, out_channels, kernel_size
        )
        self.bias = nn.Parameter(torch.randn(bias_shape))

    def forward(self, x):
        conv = self.conv_transpose
        supported = (
            x.is_cuda
            and x.dtype == torch.float32
            and conv.weight.dtype == torch.float32
            and self.bias.dtype == torch.float32
            and x.ndim == 4
            and tuple(self.bias.shape) == (conv.out_channels, 1, 1)
            and conv.in_channels + conv.out_channels + 9 <= 12288
        )

        if supported:
            return _extension.pooled_transpose_cuda(
                x.contiguous(),
                conv.weight.contiguous(),
                conv.bias.contiguous(),
                self.bias.contiguous(),
            )

        x = conv(x)
        x = x.mean(dim=(2, 3), keepdim=True)
        x = x + self.bias
        x = torch.logsumexp(x, dim=1, keepdim=True)
        return x.sum(dim=(2, 3)) * 10.0
```