How to exclude a specific tag from the list of tags for the current post?

METHOD 1 – wp_get_post_terms()

We can make use of the wpse_exclude parameter to exclude and array of terms from the list of post terms. wp_get_post_tags() internally uses wp_get_post_terms() which uses wp_get_object_terms(). When looking at the source of the latter, we see that we can make use of the wp_get_object_terms filter to filter the output from the function.

With this in mind, we can run the following filter on the output when we pass an array of id’s to wpse_exclude: (NOTE: Untested and requires PHP 5.4+)

add_filter( 'wp_get_object_terms', function ( $terms, $object_ids, $taxonomies, $args )
{
    // Lets first make sure that we have terms, and only target the post_tag taxonomy
    if (    !$terms
         || is_wp_error( $terms )
    ) 
        return $terms;

    if ( 'post_tag' !== $taxonomies )
        return $terms;

    // Now we can check if our custom argument is passed and valid
    if ( !isset( $args['wpse_exclude'] ) )
        return $terms;

    // Make sure that filds are not set to names
    if ( 'names' === $args['fields'] )
        return $terms;

    // Lets validate sanitize the array of integers, might be bit verbose though
    $excluded_id_array = filter_var(  
        $args['wpse_exclude'], 
        FILTER_VALIDATE_INT,
        [
            'flags'   => FILTER_REQUIRE_ARRAY,
            'options' => ['min_range' => 1]
        ]
    );

    if ( !$excluded_id_array )
        return $terms;

    // Everything checks out, lets exclude the terms
    $new_array = [];
    foreach ( $terms as $term ) {
        if ( in_array( $term->term_id, $excluded_id_array ) )
            continue; // Skip the excluded term

        $new_array[] = $term;
    }

    // We can now return out terms
    return $new_array;
}, 11, 4 );

USAGE

$args = [
    'wpse_exclude' => [1,2,4] // Array of tag ids to eclude
];
$tags = wp_get_post_tags( get_the_ID(), $args );

IMPORTANT NOTE ON ABOVE METHOD

The method above is quite verbose. wp_get_object_terms() (which is used internally by wp_get_post_tags()) will result in an extra db call per post. Depending on the amount of posts being returned, this method can end updoing quite a number of unnecessary db calls. It is up to you to except this extra db call per post depending on what you need to do

METHOD 2

A faster and less intrusive method would be to write a simple wrapper function for get_the_tags(). get_the_tags() uses get_the_terms() which uses all term info from the term cache. By default, any query will cache all post terms for the posts queried, so any function that uses get_the_terms() will not do any extra db call to get post term info.

IMHO, I would prefer this method above the other method as it is less verbose

function wpse_230208_get_the_tags( $post_id = 0, $exclude = [] )
{
    $post_id = filter_var( $post_id, FILTER_VALIDATE_INT );
    if ( !$post_id )
        return false;

    // Get the post tags
    $tags = get_the_tags( $post_id );

    // If there are no tags, lets bail early
    if ( !$tags )
        return false;

    // Check if we have a value for $exclude, if not, return get_the_tags
    if ( !$exclude )
        return $tags;

    // Validate the array of excluded ids
    $excluded_id_array = filter_var(  
        $exclude, 
        FILTER_VALIDATE_INT,
        [
            'flags'   => FILTER_REQUIRE_ARRAY,
            'options' => ['min_range' => 1]
        ]
    );

    if ( !$excluded_id_array )
        return $tags;

    // Lets exclude the tags
    $new_tag_array = [];
    foreach ( $tags as $tag ) {
        if ( in_array( $tag->term_id, $excluded_id_array ) )
           continue; // Skip the excluded tag

        $new_tag_array[] = $tag;
    }

    return $new_tag_array
}

USAGE

$tags = wpse_230208_get_the_tags( get_the_ID(), [1,2,4] ); // Note the array of id's to be excluded as 2nd args