def _adjust_activation_qspec(
    node: _torch.fx.Node, qspec: _Optional[_TorchQuantizationSpecBase]
) -> _Optional[_TorchQuantizationSpecBase]:
    """
    Adjust quantization spec for ops which can use fixed qparams
    or ops for which we can use affine quantization mode during
    symmetric quantization because their output is always positive.
    """
    if qspec is None:
        return qspec

    tanh_qspec = _FixedQParamsQuantizationSpec(
        dtype=_torch.uint8,
        scale=2.0 / 256.0,
        zero_point=128,
        quant_min=0,
        quant_max=255,
        qscheme=_torch.per_tensor_symmetric,
    )

    sigmoid_qspec = _FixedQParamsQuantizationSpec(
        dtype=_torch.uint8,
        scale=1.0 / 256.0,
        zero_point=0,
        quant_min=0,
        quant_max=255,
        qscheme=_torch.per_tensor_affine,
    )

    fixed_q_params_ops = {
        _torch.ops.aten.tanh.default: tanh_qspec,
        _torch.ops.aten.tanh_.default: tanh_qspec,
        _torch.ops.aten.sigmoid.default: sigmoid_qspec,
        _torch.ops.aten.sigmoid_.default: sigmoid_qspec,
        _torch.ops.aten.hardsigmoid.default: sigmoid_qspec,
        _torch.ops.aten.hardsigmoid_.default: sigmoid_qspec,
    }

    always_affine_ops = (
        _torch.ops.aten.relu.default,
        _torch.ops.aten.relu_.default,
        _torch.ops.aten.relu6.default,
        _torch.ops.aten.relu6_.default,
    )

    # ReLU6 activation maps to _torch.ops.aten.hardtanh.default with
    # min_val = 0 and max_val = 6
    is_always_affine_op = node.target in always_affine_ops or (
        node.target
        in [_torch.ops.aten.hardtanh.default, _torch.ops.aten.hardtanh_.default]
        and node.args[1] == 0  # min_val, corresponding to ReLU6
        and node.args[2] == 6  # max_val, corresponding to ReLU6
    )

    if node.target in fixed_q_params_ops:
        return _TorchQuantizationSpec(
            observer_or_fake_quant_ctr=qspec.observer_or_fake_quant_ctr,
            dtype=qspec.dtype,
            qscheme=fixed_q_params_ops[node.target].qscheme,
        )
        # FIXME: Because of a bug in PyTorch in function _create_obs_or_fq_from_qspec
        #        in module torch/ao/quantization/fx/prepare.py  which creates a
        #        FixedQParamsFakeQuantize partial, instead of an instance, we cannot
        #        actually create FixedQParamsQuantizationSpec
    if is_always_affine_op:
        return _TorchQuantizationSpec(
            observer_or_fake_quant_ctr=qspec.observer_or_fake_quant_ctr,
            dtype=qspec.dtype,
            qscheme=_torch.per_tensor_affine,
        )
    return qspec

    Adjust quantization spec for ops which can use fixed qparams
    or ops for which we can use affine quantization mode during
    symmetric quantization because their output is always positive.
    
coremltools/optimize/torch/quantization/_coreml_quantizer_utils.py