How do I bulk delete taxonomy terms?
Before you clean the vocabulary you need to change the taxonomy reference field, to do this you can use this code:

$nids = \Drupal::entityQuery('node')-&gt;condition('type','YOUR_CONTENT_TYPE')-&gt;execute();
$nodes =  \Drupal\node\Entity\Node::loadMultiple($nids);

foreach($nodes as $node) {
  // Change your term here
  $node-&gt;field_YOUR_TAXONOMY_REFERENCE_FIELD-&gt;value = '';
 $node-&gt;save();
}


To clean the vocabulary use this modification of a drush command that you can see in https://github.com/adrian-cid/drush_commands/blob/master/drush_taxonomy.drush.inc

You need to pass an array of vocabularies names to clean.

I use the dpm() function (you need to install Devel) to show the messages, but you can change it if you want.

function taxonomy_vocabulary_clean(array $names) {
  if (!empty($names)) {
    // Check for duplicate ids.
    $test_names = array_unique($names);
    if (count($test_names) != count($names)) {
      dpm('You have duplicate vocabulary names.');
      return;
    }
    //Searching the vocabularies in the site
    $vocabulary_in_db = array_keys(Drupal\taxonomy\Entity\Vocabulary::loadMultiple());
    $vocabulary_non_existent = array_diff($names, $vocabulary_in_db);
    $vocabulary_existent = array_diff($names, $vocabulary_non_existent);

    if (count($vocabulary_existent) == 0) {
      dpm("The desired vocabulary to clean doesn't exists.");
      return;
    }
    if (count($vocabulary_non_existent)) {
      dpm('Non-existent vocabulary:');
      dpm(implode(' ', $vocabulary_non_existent));
    }

    foreach ($vocabulary_existent as $name) {
      $tids = \Drupal::entityQuery('taxonomy_term')
        -&gt;condition('vid', $name)
        -&gt;execute();

      $controller = \Drupal::entityTypeManager()-&gt;getStorage('taxonomy_term');
      $entities = $controller-&gt;loadMultiple($tids);
      $controller-&gt;delete($entities);
    }
    dpm('Vocabulary cleaned:');
    dpm(implode(' ', $vocabulary_existent));
  }
  else {
    dpm('You must enter at least one vocabulary name.');
  }
}


Using the function:

taxonomy_vocabulary_clean(['tags', 'my_vocabulary_machine_name']);


The Drupal 7 code:

function taxonomy_vocabulary_clean(array $names) {
  if (!empty($names)) {
    // Check for duplicate ids.
    $test_names = array_unique($names);
    if (count($test_names) != count($names)) {
      dpm('You have duplicate vocabulary names.'));
      return;
    }
    //Searching the vocabularies in the site
    $vocabulary_in_db = array_column(taxonomy_get_vocabularies(), 'machine_name');
    $vocabulary_non_existent = array_diff($names, $vocabulary_in_db);
    $vocabulary_existent = array_diff($names, $vocabulary_non_existent);

    if(count($vocabulary_existent) == 0) {
      dpm("The desired vocabulary to clean doesn't exists.");
      return;
    }
    if(count($vocabulary_non_existent)) {
      dpm('Non-existent vocabulary:');
      dpm(implode(' ', $vocabulary_non_existent));
    }

    foreach ($vocabulary_existent as $name) {
      $vid = taxonomy_vocabulary_machine_name_load($name)-&gt;vid;
      foreach(taxonomy_get_tree($vid) as $term) {
        taxonomy_term_delete($term-&gt;tid);
      }
    }
    dpm('Vocabulary cleaned:');
    dpm(implode(' ', $vocabulary_existent));
  }
  else {
    dpm('You must enter at least one vocabulary name.');
  }
}