모델 적응을 통한 스크립트 작성 결과 개선

개요

Speech-to-Text가 특정 단어나 구문을 제안된 다른 단어나 구문보다 더 자주 인식하도록 하려면 모델 적응 기능을 사용하면 됩니다. 예를 들어 'weather'라는 단어가 자주 등장하는 오디오 데이터가 있다고 가정합니다. Speech-to-Text가 단어 'weather'를 발견할 때 이 단어를 'whether'보다는 'weather'로 더 많이 변환하도록 하려고 합니다. 이 경우 모델 적응을 사용하여 Speech-to-Text가 'weather'를 편향되게 인식하도록 할 수 있습니다.

모델 적응은 특히 다음과 같은 사용 사례에 유용합니다.

  • 오디오 데이터에서 자주 나타나는 단어와 구문의 정확도를 향상시킵니다. 예를 들어 일반적으로 사용자가 말하는 음성 명령어를 인식 모델에 알릴 수 있습니다.

  • Speech-to-Text에서 인식되는 단어의 어휘를 확장합니다. Speech-to-Text에는 매우 많은 어휘가 포함되어 있습니다. 하지만 오디오 데이터에 일반적으로 사용되지 않는 단어(예: 고유 명사 또는 도메인 관련 단어)가 포함된 경우 모델 적응을 사용하여 이를 추가할 수 있습니다.

  • 제공된 오디오에 노이즈가 있거나 오디오가 그다지 선명하지 않을 때 음성 텍스트 변환의 정확도를 향상시킵니다.

원하는 경우 모델 적응 부스트 기능을 사용하여 인식 모델의 편향을 미세 조정할 수 있습니다.

단어 및 구문 인식 향상

Speech-to-Text가 오디오 데이터를 텍스트로 변환할 때 'weather'라는 단어가 인식될 확률을 높이려면 SpeechAdaptation 리소스의 PhraseSet객체에 이 단일어를 전달할 수 있습니다.

여러 단어로 구성된 구문을 제공하면 Speech-to-Text가 이러한 단어를 순서대로 인식할 가능성이 높아집니다. 구문을 제공하면 개별 단어를 포함하여 구문의 일부분이 인식될 수 있는 가능성도 높아집니다. 이러한 구문의 수와 크기에 대한 한도는 콘텐츠 한도 페이지를 참조하세요.

클래스를 사용하여 인식 향상

클래스는 자연어에서 발생하는 화폐 단위 및 달력 날짜와 같은 일반적인 개념을 나타냅니다. 클래스를 사용하면 일반적인 개념으로 매핑되지만 항상 동일한 단어나 문구가 포함되지 않는 큰 단어 그룹의 텍스트 변환 정확도를 향상시킬 수 있습니다.

예를 들어 오디오 데이터에 사람들이 말한 자신의 상세 주소가 녹음되어 있다고 가정해 보겠습니다. 이 오디오에는 누군가 말한 "My house is 123 Main Street, the fourth house on the left."가 녹음되어 있을 수 있습니다. 이 경우 Speech-to-Text는 첫 번째 숫자 시퀀스인 '123'을 서수 '백 이십 세 번째'가 아닌 주소로 인식하도록 하려고 합니다. 하지만 모든 사람들이 '123 Main Street'에 거주하는 것은 아니기 때문에 가능한 모든 상세주소를 PhraseSet 리소스에 나열하는 것은 실행 불가능합니다. 대신 클래스를 사용하면 실제 숫자에 관계없이 번지 수로 인식되도록 할 수 있습니다. 이 예시에서 Speech-to-Text는 '123 Main Street' 및 '987 Grand Boulevard'와 같은 문구를 더 정확하게 텍스트로 변환할 수 있습니다. 숫자가 모두 번지 수로 인식되기 때문입니다.

클래스 토큰

모델 적응에 클래스를 사용하려면 PhraseSet 리소스의 phrases 필드에 클래스 토큰을 포함합니다. 사용 중인 언어에 사용 가능한 토큰을 확인하려면 지원되는 클래스 토큰 목록을 참조하세요. 예를 들어 소스 오디오에서 번지 수를 더욱 정확하게 텍스트로 변환하려면 PhraseSet.의 구문 내에서 $ADDRESSNUM 값을 제공합니다.

클래스를 phrases 배열에서 독립형 항목으로 사용하거나 클래스 토큰 한 개 이상을 여러 단어로 구성된 긴 구문에 삽입할 수 있습니다. 예를 들어 클래스 토큰을 ["my address is $ADDRESSNUM"] 문자열에 포함하면 더 긴 구문에 번지 수를 표시할 수 있습니다. 하지만 오디오에 'I am at 123 Main Street'와 같이 비슷하지만 동일하지 않은 문구가 포함된 경우에는 이 문구가 도움이 되지 않습니다. 비슷한 구문을 인식하려면 ["my address is $ADDRESSNUM", "$ADDRESSNUM"]과 같이 클래스 토큰 자체를 추가해야 합니다. 형식이 잘못되었거나 유효하지 않은 클래스 토큰을 사용하면 Speech-to-Text는 오류를 트리거하지 않고 토큰을 무시하지만 구문의 나머지 부분을 컨텍스트에 계속 사용합니다.

커스텀 클래스

또한 자체 CustomClass를 만들 수도 있습니다. 이는 관련된 항목이나 값의 맞춤 목록으로 구성된 클래스입니다. 예를 들어 수백 개의 지역별 음식점 이름 중에서 어느 한 개가 포함되었을 가능성이 있는 오디오 데이터를 텍스트로 변환하려고 합니다. 일반 발화에서 음식점 이름이 나오는 것은 상대적으로 드물기 때문에 인식 모델에서 '올바른' 답변으로 선택될 가능성은 낮습니다. 커스텀 클래스를 사용하면 오디오에서 이름이 나타날 때 이러한 이름이 올바르게 식별되도록 인식 모델을 편향되게 할 수 있습니다.

커스텀 클래스를 사용하려면 각 음식점 이름이 ClassItem으로 포함된 CustomClass 리소스를 만듭니다. 커스텀 클래스는 사전 빌드된 클래스 토큰과 동일한 방식으로 작동합니다. phrase에는 사전 빌드된 클래스 토큰 및 커스텀 클래스가 모두 포함될 수 있습니다.

부스트를 사용하여 변환 결과 미세 조정

기본적으로 모델 적응은 상대적으로 단일 단어 구문에서 효과가 적게 나타납니다. 모델 적응 부스트 기능을 사용하면 일부 구문에 다른 구문보다 더 많은 가중치를 할당하여 인식 모델 편향을 높일 수 있습니다. 다음 사항이 모두 해당되는 경우 부스트를 구현하는 것이 좋습니다.

  1. 이미 모델 조정을 구현했습니다.
  2. 스트립트 작성 결과에서 모델 적응 효과의 강도를 더욱 조정하려고 합니다. 사용 중인 언어에서 부스트 기능 사용 여부를 알아보려면 언어 지원 페이지를 참조하세요.

예를 들어 사람들이 'fare to get into the county fair'에 대해 묻는 녹음이 많이 있고 단어 'fare'보다 'fair'가 더 자주 나타난다고 가정해 보겠습니다. 이 경우 모델 적응을 사용하여 모델이 PhraseSet 리소스에서 phrases을 추가하여 'fair'와 'fare'를 모두 인식하도록 할 수 있습니다. 그러면 예를 들어 Speech-to-Text가 'hare' 또는 'lair'보다 'fair' 및 'fare'를 더 자주 인식합니다.

하지만 'fair'가 오디오에 더 자주 등장하므로 'fare'보다 더 자주 인식되어야 합니다. Speech-to-Text API를 사용하여 오디오를 이미 텍스트 변환한 후 올바른 단어('fair')를 인식하는 데 많은 오류가 발생한 것으로 확인되었을 수 있습니다. 이 경우 부스트 기능을 사용하여 'fare'보다 'fair에 더 높은 부스트 값을 할당해야 할 수 있습니다. 'fair'에 할당되는 가중치 값이 높을수록 Speech-to-Text API가 'fare'보다는 'fair'를 선택할 가능성이 높아집니다. 부스트 값이 없으면 인식 모델이 'fair'와 'fare'를 인식할 확률은 동일합니다.

부스트 기본사항

부스트를 사용하면 PhraseSet 리소스의 phrase 항목에 가중치 값이 할당됩니다. Speech-to-Text는 오디오 데이터의 단어에 가능한 변환 텍스트를 선택할 때 이 가중치를 참조합니다. 이 값이 높을수록 Speech-to-Text가 가능한 대체 변환 텍스트 중에서 해당 구문을 선택할 확률이 높아집니다.

여러 단어로 된 문구에 부스트 값을 할당하면 전체 문구에만 부스트가 적용됩니다. 예를 들어 'My favorite exhibit at the American Museum of Natural History is the blue whale'이라는 문구에 무스트 값을 할당할 수 있습니다. 이 문구를 phrase 객체에 추가하고 부스트 값을 할당하면 인식 모델이 문구 전체를 단어 대 단어로 인식할 가능성이 높아집니다.

여러 단어 문구를 부스트하여 원하는 결과를 얻지 못한 경우에는 문구를 추가 phrase 항목으로 만들고 각 항목에 부스트 값을 할당하는 모든 바이그램(순서대로 2단어)을 추가하는 것이 좋습니다. 위 예시에 이어서 'my favorite', 'my favorite exhibit', 'favorite exhibit', 'my favorite exhibit at the American Museum of Natural History', 'American Museum of Natural History', 'blue whale' 등으로 바이그램 및 엔드그램(2단어 초과)을 추가하여 조사해볼 수 있습니다. 그러면 STT 인식 모델이 원래 부스트된 문구의 일부를 포함하지만 단어 대 단어로 완전히 일치하지는 않는 관련 문구를 오디오에서 인식할 가능성이 더 높아집니다.

부스트 값 설정

부스트 값은 0보다 큰 부동 소수점 값이어야 합니다. 부스트 값의 실제 최대 한도는 20입니다. 최상의 결과를 얻으려면 정확한 텍스트 변환 결과를 얻을 때까지 부스트 값을 늘리거나 줄여서 텍스트 변환 결과를 실험합니다.

부스트 값이 높을수록 오디오에 포함된 단어나 구문이 Speech-to-Text에서 올바르게 인식되지 않는 거짓음성이 발생할 확률이 낮아집니다. 그러나 부스트는 오디오에 포함되지 않은 단어나 구문이 변환 텍스트에 나타나는 거짓양성을 증가시킬 수도 있습니다.

모델 적응 사용 사례의 예시

다음 예시는 모델 적응을 사용하여 'The word is fare'라고 말하는 사람의 오디오 녹음을 스크립트로 작성하는 과정을 안내합니다. 이 경우 음성 적응이 없으면 Speech-to-Text가 'fair'라는 단어를 식별합니다. 음성 적응을 사용하는 Speech-to-Text는 대신 'fare'라는 단어를 식별할 수 있습니다.

시작하기 전에

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. Enable the Speech-to-Text APIs.

    Enable the APIs

  5. 프로젝트에 다음 역할이 있는지 확인합니다. Cloud Speech Administrator

    역할 확인

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 주 구성원 열에서 이메일 주소가 있는 행을 찾습니다.

      이메일 주소가 열에 없으면 역할이 없는 것입니다.

    4. 이메일 주소가 있는 행에 대해 역할 열에서 역할 목록에 필요한 역할이 있는지 확인합니다.

    역할 부여

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 액세스 권한 부여를 클릭합니다.
    4. 새 주 구성원 필드에 이메일 주소를 입력합니다.
    5. 역할 선택 목록에서 역할을 선택합니다.
    6. 역할을 추가로 부여하려면 다른 역할 추가를 클릭하고 각 역할을 추가합니다.
    7. 저장을 클릭합니다.
  6. Install the Google Cloud CLI.
  7. To initialize the gcloud CLI, run the following command:

    gcloud init
  8. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  9. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  10. Enable the Speech-to-Text APIs.

    Enable the APIs

  11. 프로젝트에 다음 역할이 있는지 확인합니다. Cloud Speech Administrator

    역할 확인

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 주 구성원 열에서 이메일 주소가 있는 행을 찾습니다.

      이메일 주소가 열에 없으면 역할이 없는 것입니다.

    4. 이메일 주소가 있는 행에 대해 역할 열에서 역할 목록에 필요한 역할이 있는지 확인합니다.

    역할 부여

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 액세스 권한 부여를 클릭합니다.
    4. 새 주 구성원 필드에 이메일 주소를 입력합니다.
    5. 역할 선택 목록에서 역할을 선택합니다.
    6. 역할을 추가로 부여하려면 다른 역할 추가를 클릭하고 각 역할을 추가합니다.
    7. 저장을 클릭합니다.
  12. Install the Google Cloud CLI.
  13. To initialize the gcloud CLI, run the following command:

    gcloud init
  14. 클라이언트 라이브러리는 애플리케이션 기본 사용자 인증 정보를 사용하여 간편하게 Google API를 인증하고 API에 요청을 보낼 수 있습니다. 애플리케이션 기본 사용자 인증 정보를 사용하면 애플리케이션을 로컬에서 테스트하고 기본 코드를 변경하지 않은 상태로 배포할 수 있습니다. 자세한 내용은 클라이언트 라이브러리 사용 인증을 참조하세요.

  15. If you're using a local shell, then create local authentication credentials for your user account:

    gcloud auth application-default login

    You don't need to do this if you're using Cloud Shell.

또한 클라이언트 라이브러리를 설치했는지 확인합니다.

PhraseSet를 사용하여 텍스트 변환 개선

  1. 다음 샘플은 'fare' 구문으로 PhraseSet를 빌드하고 인식 요청에 inline_phrase_set로 추가합니다.

Python

import os

from google.cloud.speech_v2 import SpeechClient
from google.cloud.speech_v2.types import cloud_speech

PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")


def adaptation_v2_inline_phrase_set(audio_file: str) -> cloud_speech.RecognizeResponse:
    """Enhances speech recognition accuracy using an inline phrase set.
    The inline custom phrase set helps the recognizer produce more accurate transcriptions for specific terms.
    Phrases are given a boost to increase their chances of being recognized correctly.
    Args:
        audio_file (str): Path to the local audio file to be transcribed.
    Returns:
        cloud_speech.RecognizeResponse: The full response object which includes the transcription results.
    """

    # Instantiates a client
    client = SpeechClient()

    # Reads a file as bytes
    with open(audio_file, "rb") as f:
        audio_content = f.read()

    # Build inline phrase set to produce a more accurate transcript
    phrase_set = cloud_speech.PhraseSet(
        phrases=[{"value": "fare", "boost": 10}, {"value": "word", "boost": 20}]
    )
    adaptation = cloud_speech.SpeechAdaptation(
        phrase_sets=[
            cloud_speech.SpeechAdaptation.AdaptationPhraseSet(
                inline_phrase_set=phrase_set
            )
        ]
    )
    config = cloud_speech.RecognitionConfig(
        auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
        adaptation=adaptation,
        language_codes=["en-US"],
        model="short",
    )

    # Prepare the request which includes specifying the recognizer, configuration, and the audio content
    request = cloud_speech.RecognizeRequest(
        recognizer=f"projects/{PROJECT_ID}/locations/global/recognizers/_",
        config=config,
        content=audio_content,
    )

    # Transcribes the audio into text
    response = client.recognize(request=request)

    for result in response.results:
        print(f"Transcript: {result.alternatives[0].transcript}")

    return response
  1. 이 샘플은 동일한 구문으로 PhraseSet 리소스를 만든 후 인식 요청에서 참조합니다.

Python

import os

from google.cloud.speech_v2 import SpeechClient
from google.cloud.speech_v2.types import cloud_speech

PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")


def adaptation_v2_phrase_set_reference(
    audio_file: str,
    phrase_set_id: str,
) -> cloud_speech.RecognizeResponse:
    """Transcribe audio files using a PhraseSet.
    Args:
        audio_file (str): Path to the local audio file to be transcribed.
        phrase_set_id (str): The unique ID of the PhraseSet to use.
    Returns:
        cloud_speech.RecognizeResponse: The full response object which includes the transcription results.
    """

    # Instantiates a client
    client = SpeechClient()

    # Reads a file as bytes
    with open(audio_file, "rb") as f:
        audio_content = f.read()

    # Creating operation of creating the PhraseSet on the cloud.
    operation = client.create_phrase_set(
        parent=f"projects/{PROJECT_ID}/locations/global",
        phrase_set_id=phrase_set_id,
        phrase_set=cloud_speech.PhraseSet(phrases=[{"value": "fare", "boost": 10}]),
    )
    phrase_set = operation.result()

    # Add a reference of the PhraseSet into the recognition request
    adaptation = cloud_speech.SpeechAdaptation(
        phrase_sets=[
            cloud_speech.SpeechAdaptation.AdaptationPhraseSet(
                phrase_set=phrase_set.name
            )
        ]
    )

    # Automatically detect audio encoding. Use "short" model for short utterances.
    config = cloud_speech.RecognitionConfig(
        auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
        adaptation=adaptation,
        language_codes=["en-US"],
        model="short",
    )
    #  Prepare the request which includes specifying the recognizer, configuration, and the audio content
    request = cloud_speech.RecognizeRequest(
        recognizer=f"projects/{PROJECT_ID}/locations/global/recognizers/_",
        config=config,
        content=audio_content,
    )
    # Transcribes the audio into text
    response = client.recognize(request=request)

    for result in response.results:
        print(f"Transcript: {result.alternatives[0].transcript}")

    return response

CustomClass를 사용하여 텍스트 변환 결과 개선

  1. 다음 샘플은 'fare' 항목과 'fare' 이름으로 CustomClass를 빌드합니다. 그런 다음 인식 요청의 inline_phrase_set 내에서 CustomClass를 참조합니다.

Python

import os

from google.cloud.speech_v2 import SpeechClient
from google.cloud.speech_v2.types import cloud_speech

PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")


def adaptation_v2_inline_custom_class(
    audio_file: str,
) -> cloud_speech.RecognizeResponse:
    """Transcribe audio file using inline custom class.
    The inline custom class helps the recognizer produce more accurate transcriptions for specific terms.
    Args:
        audio_file (str): Path to the local audio file to be transcribed.
    Returns:
        cloud_speech.RecognizeResponse: The response object which includes the transcription results.
    """
    # Instantiates a client
    client = SpeechClient()

    # Reads a file as bytes
    with open(audio_file, "rb") as f:
        audio_content = f.read()

    # Define an inline custom class to enhance recognition accuracy with specific items like "fare" etc.
    custom_class_name = "your-class-name"
    custom_class = cloud_speech.CustomClass(
        name=custom_class_name,
        items=[{"value": "fare"}],
    )

    # Build inline phrase set to produce a more accurate transcript
    phrase_set = cloud_speech.PhraseSet(
        phrases=[{"value": custom_class_name, "boost": 20}]
    )
    adaptation = cloud_speech.SpeechAdaptation(
        phrase_sets=[
            cloud_speech.SpeechAdaptation.AdaptationPhraseSet(
                inline_phrase_set=phrase_set
            )
        ],
        custom_classes=[custom_class],
    )
    config = cloud_speech.RecognitionConfig(
        auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
        adaptation=adaptation,
        language_codes=["en-US"],
        model="short",
    )

    # Prepare the request which includes specifying the recognizer, configuration, and the audio content
    request = cloud_speech.RecognizeRequest(
        recognizer=f"projects/{PROJECT_ID}/locations/global/recognizers/_",
        config=config,
        content=audio_content,
    )

    # Transcribes the audio into text
    response = client.recognize(request=request)

    for result in response.results:
        print(f"Transcript: {result.alternatives[0].transcript}")

    return response
  1. 이 샘플은 동일한 항목으로 CustomClass 리소스를 만듭니다. 그런 다음 CustomClass 리소스 이름을 참조하는 구문으로 PhraseSet 리소스를 만듭니다. 그런 다음 인식 요청에서 PhraseSet 리소스를 참조합니다.

Python

import os

from google.cloud.speech_v2 import SpeechClient
from google.cloud.speech_v2.types import cloud_speech

PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")


def adaptation_v2_custom_class_reference(
    audio_file: str, phrase_set_id: str, custom_class_id: str
) -> cloud_speech.RecognizeResponse:
    """Transcribe audio file using a custom class.
    Args:
        audio_file (str): Path to the local audio file to be transcribed.
        phrase_set_id (str): The unique ID of the phrase set to use.
        custom_class_id (str): The unique ID of the custom class to use.
    Returns:
        cloud_speech.RecognizeResponse: The full response object which includes the transcription results.
    """
    # Instantiates a speech client
    client = SpeechClient()

    # Reads a file as bytes
    with open(audio_file, "rb") as f:
        audio_content = f.read()

    # Create a custom class to improve recognition accuracy for specific terms
    custom_class = cloud_speech.CustomClass(items=[{"value": "fare"}])
    operation = client.create_custom_class(
        parent=f"projects/{PROJECT_ID}/locations/global",
        custom_class_id=custom_class_id,
        custom_class=custom_class,
    )
    custom_class = operation.result()

    # Create a persistent PhraseSet to reference in a recognition request
    created_phrase_set = cloud_speech.PhraseSet(
        phrases=[
            {
                "value": f"${{{custom_class.name}}}",
                "boost": 20,
            },  # Using custom class reference
        ]
    )
    operation = client.create_phrase_set(
        parent=f"projects/{PROJECT_ID}/locations/global",
        phrase_set_id=phrase_set_id,
        phrase_set=created_phrase_set,
    )
    phrase_set = operation.result()

    # Add a reference of the PhraseSet into the recognition request
    adaptation = cloud_speech.SpeechAdaptation(
        phrase_sets=[
            cloud_speech.SpeechAdaptation.AdaptationPhraseSet(
                phrase_set=phrase_set.name
            )
        ]
    )
    # Automatically detect the audio's encoding with short audio model
    config = cloud_speech.RecognitionConfig(
        auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),
        adaptation=adaptation,
        language_codes=["en-US"],
        model="short",
    )

    # Create a custom class to reference in a PhraseSet
    request = cloud_speech.RecognizeRequest(
        recognizer=f"projects/{PROJECT_ID}/locations/global/recognizers/_",
        config=config,
        content=audio_content,
    )

    # Transcribes the audio into text
    response = client.recognize(request=request)

    for result in response.results:
        print(f"Transcript: {result.alternatives[0].transcript}")

    return response

삭제

이 페이지에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 다음 단계를 수행합니다.

  1. 선택사항: 만든 사용자 인증 정보를 취소하고 로컬 사용자 인증 정보 파일을 삭제합니다.

    gcloud auth application-default revoke
  2. Optional: Revoke credentials from the gcloud CLI.

    gcloud auth revoke

콘솔

  • In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  • In the project list, select the project that you want to delete, and then click Delete.
  • In the dialog, type the project ID, and then click Shut down to delete the project.
  • gcloud

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

    다음 단계