def add_embedding(
        self,
        name,
        W,
        b,
        input_dim,
        output_channels,
        has_bias,
        input_name,
        output_name,
        is_quantized_weight=False,
        quantization_type="linear",
        nbits=8,
        quant_scale=None,
        quant_bias=None,
        quant_lut=None,
    ):
        """
        Add an embedding layer to the model.
        Refer to the ``EmbeddingLayerParams`` message in the specification
        (NeuralNetwork.proto) for more details.

        Parameters
        ----------
        name: str
            The name of this layer.
        W: float32 numpy.array or bytes()
            Weight matrix of shape ``(output_channels, input_dim)``.
            If ``W`` is of type ``bytes()`` (quantized to 1-8 bits), other
            quantization related arguments must be provided as well (see below).
        b: numpy.array
            Bias vector of shape ``(output_channels, )``.
        input_dim: int
            Size of the vocabulary (1 + maximum integer index of the words).
        output_channels: int
            Number of output channels.
        has_bias: boolean
            Whether the bias vector of this layer is ignored in the ``spec``.

            - If True, the bias vector of this layer is not ignored.
            - If False, the bias vector is ignored.

        input_name: str
            The input blob name of this layer.
        output_name: str
            The output blob name of this layer.


        Quantization arguments expected, when ``W`` is of type ``bytes()``:

        is_quantized_weight: bool
            Set it to true when ``W`` is of type ``bytes()``, representing quantized weights.

        quantization_type: str
            When weights are quantized (that is, ``W`` is of type ``bytes()``),
            this should be either ``"linear"`` or ``"lut"``.

        nbits: int
            Should be between 1 and 8 (inclusive). Number of bits per weight value.

        quant_scale: numpy.array(dtype=numpy.float32)
            Scale vector to be used with linear quantization.
            Must be of length either 1 or output_channels.

        quant_bias: numpy.array(dtype=numpy.float32)
            Bias vector to be used with linear quantization.
            Must be of length either 1 or output_channels.

        quant_lut: numpy.array(dtype=numpy.float32)
            The LUT (look up table) to be used with LUT quantization.
            Must be of length 2^n bits.

        See Also
        --------
        add_inner_product
        """

        spec_layer = self._add_generic_layer(name, [input_name], [output_name])

        # Fill in the parameters
        spec_layer_params = spec_layer.embedding

        spec_layer_params.inputDim = input_dim
        spec_layer_params.outputChannels = output_channels
        spec_layer_params.hasBias = has_bias

        weights = spec_layer_params.weights
        if not is_quantized_weight:
            weights.floatValue.extend(W.flatten())
        else:
            _verify_quantization_arguments(
                weight=W,
                output_channels=output_channels,
                quantization_type=quantization_type,
                nbits=nbits,
                quant_scale=quant_scale,
                quant_bias=quant_bias,
                quant_lut=quant_lut,
            )

            _fill_quantized_weights(
                weights_message=weights,
                W=W,
                quantization_type=quantization_type,
                nbits=nbits,
                quant_scale=quant_scale,
                quant_bias=quant_bias,
                quant_lut=quant_lut,
            )

        if has_bias:
            bias = spec_layer_params.bias
            bias.floatValue.extend(b.flatten())

        return spec_layer

        Add an embedding layer to the model.
        Refer to the ``EmbeddingLayerParams`` message in the specification
        (NeuralNetwork.proto) for more details.

        Parameters
        ----------
        name: str
            The name of this layer.
        W: float32 numpy.array or bytes()
            Weight matrix of shape ``(output_channels, input_dim)``.
            If ``W`` is of type ``bytes()`` (quantized to 1-8 bits), other
            quantization related arguments must be provided as well (see below).
        b: numpy.array
            Bias vector of shape ``(output_channels, )``.
        input_dim: int
            Size of the vocabulary (1 + maximum integer index of the words).
        output_channels: int
            Number of output channels.
        has_bias: boolean
            Whether the bias vector of this layer is ignored in the ``spec``.

            - If True, the bias vector of this layer is not ignored.
            - If False, the bias vector is ignored.

        input_name: str
            The input blob name of this layer.
        output_name: str
            The output blob name of this layer.


        Quantization arguments expected, when ``W`` is of type ``bytes()``:

        is_quantized_weight: bool
            Set it to true when ``W`` is of type ``bytes()``, representing quantized weights.

        quantization_type: str
            When weights are quantized (that is, ``W`` is of type ``bytes()``),
            this should be either ``"linear"`` or ``"lut"``.

        nbits: int
            Should be between 1 and 8 (inclusive). Number of bits per weight value.

        quant_scale: numpy.array(dtype=numpy.float32)
            Scale vector to be used with linear quantization.
            Must be of length either 1 or output_channels.

        quant_bias: numpy.array(dtype=numpy.float32)
            Bias vector to be used with linear quantization.
            Must be of length either 1 or output_channels.

        quant_lut: numpy.array(dtype=numpy.float32)
            The LUT (look up table) to be used with LUT quantization.
            Must be of length 2^n bits.

        See Also
        --------
        add_inner_product
        
coremltools/models/neural_network/builder.py