실시간 스트리밍 인식
    • PDF

    실시간 스트리밍 인식

    • PDF

    기사 요약

    Classic/VPC 환경에서 이용 가능합니다.

    실시간으로 16kHZ, 1 Channel, 16 bits per sample의 PCM(헤더가 없는 WAV 파일) 형식의 음성 데이터를 인식하고 텍스트로 변환합니다. gRPC 방식을 통해서만 접근이 가능합니다.

    요청

    요청 형식을 설명합니다. 요청 형식은 다음과 같습니다.

    HostPort
    clovaspeech-gw.ncloud.com50051

    요청 순서

    gRPC 방식을 통해 인식을 요청하는 방법은 다음과 같습니다.

    1. 사전 준비
    2. Config JSON
    3. 인식(Recognize)
    참고

    Rocky Linux 환경을 기준으로 설명합니다.

    1. Protoc Compiler 설치 및 준비

    API를 사용하기 위한 사전 준비를 위해 gRPC 사이트를 참조하여 Protoc Compiler를 설치합니다. 설치 후 Python과 Java 중 원하는 언어를 선택한 다음 API의 인터페이스가 정의된 'nest.proto' 파일을 통해 Compiler를 호출합니다.
    Protoc Compiler를 설치하고 gRPC 코드를 생성하는 방법은 다음과 같습니다.

    1. Protoc Compiler를 설치할 서버에 원격 접속해 주십시오.

    2. gRPC 사용을 위한 패키지와 플러그인을 설치해 주십시오.

      • Rocky Linux: Python

        # 최신 상태 확인
        sudo dnf update
        
        # Python 설치 : Linux 서버에 Python을 설치합니다.
        sudo dnf install python3
        
        # pip 설치 및 업그레이드 : pip는 Python용 패키지 설치 프로그램입니다.
        sudo dnf install python3-pip
        pip3 install --upgrade pip
        
        # grpcio-tools 설치 : pip를 사용하여 'grpcio-tools'를 설치합니다.
        pip3 install grpcio-tools
        
        # nest.proto 파일 생성
        touch nest.proto
        
        # protoc compiler로 nest.proto 파일 컴파일
        python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. nest.proto
        
      • Rocky Linux: Java

        # protoc-gen-grpc-java 플러그인 다운로드 (버전 번호는 확인 필요 https://github.com/grpc/grpc-java/releases)
        curl -OL https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.66.0/protoc-gen-grpc-java-1.66.0-linux-x86_64.exe
        
        # PATH에 추가
        mv protoc-gen-grpc-java-1.66.0-linux-x86_64.exe /usr/local/bin/protoc-gen-grpc-java
        
        # 실행 권한으로 바꾸기
        chmod +x /usr/local/bin/protoc-gen-grpc-java
        
        # 설치 확인
        protoc-gen-grpc-java --version
        
        # nest.proto 파일 생성
        touch nest.proto
        
        # protoc compiler로 nest.proto 파일 컴파일
        protoc --proto_path=. --java_out=output/directory --grpc-java_out=output/directory nest.proto
        
    3. 'nest.proto' 파일을 열어 다음 코드를 입력하고 gRPC 코드를 생성해 주십시오.

      syntax = "proto3";
      option java_multiple_files = true;
      package com.nbp.cdncp.nest.grpc.proto.v1;
      
      enum RequestType {
        CONFIG = 0;
        DATA = 1;
      }
      
      message NestConfig {
        string config = 1;
      }
      
      message NestData {
        bytes chunk = 1;
        string extra_contents = 2;
      }
      message NestRequest {
        RequestType type = 1;
        oneof part {
          NestConfig config = 2;
          NestData data = 3;
        }
      }
      
      message NestResponse {
        string contents = 1;
      }
      service NestService {
        rpc recognize(stream NestRequest) returns (stream NestResponse){};
      }
      

    2. 인증(Authorization)

    Protoc Compiler를 통해 gRPC 코드 생성을 완료한 후 인증을 진행합니다. 인증은 API 호출 시 Authorization 헤더에 Bearer 토큰을 포함하여 서버에 무결성을 인증하는 방식으로 진행합니다. 인증 진행 시 다음 내용을 주의해 주십시오.

    • gRPC Channel을 설정하고, nest_grpc_pb2의 Client Side Proxy인 stub을 생성합니다.
    • stub 생성 후 recognize 메서드에 인증 키가 있는 Metadata(메타 데이터)를 포함시켜 원하는 함수를 실행합니다.
      • 실시간 스트리밍 인식 API는 Free 플랜에서는 지원하지 않으며, Basic 장문 인식 플랜에서만 지원합니다.

    인증 헤더

    인증 헤더는 다음과 같습니다.

    헤더명설명
    AuthorizationBearer ${secretKey}

    인증 순서

    인증 방법은 다음과 같습니다.

    Python

    Rocky Linux 환경에서 Python을 사용하여 인증하는 방법은 다음과 같습니다.

    1. Python 파일을 생성해 주십시오. 여기에서는 파일 이름을 main.py로 지정했습니다.
      touch main.py
      
    2. main.py에 다음 내용을 추가해 주십시오.
      import grpc
      import json
      
      import nest_pb2
      import nest_pb2_grpc
      
      channel = grpc.secure_channel(
              'clovaspeech-gw.ncloud.com:50051',
              grpc.ssl_channel_credentials()
      )
      client = NestServiceStub(channel)
      metadata = (("authorization", f"Bearer {secretKey}"),) #소문자 authorization 필수 / secretkey는 장문인식 도메인에서 확인
      call = client.YourMethod(YourRequest(), metadata=metadata)
      

    Java

    Rocky Linux 환경에서 Java를 사용하여 인증하는 방법은 다음과 같습니다.

    1. Java 파일을 생성해 주십시오. 여기에서는 파일 이름을 main.java로 지정했습니다.
      touch main.java
      
    2. main.java에 다음 내용을 추가해 주십시오.
      ManagedChannel channel = NettyChannelBuilder
                  .forTarget("clovaspeech-gw.ncloud.com:50051")
                  .useTransportSecurity()
                  .build();
      NestServiceGrpc.NestServiceStub client = NestServiceGrpc.newStub(channel);
      Metadata metadata = new Metadata();
      metadata.put(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER),
                   "Bearer ${secretKey}");
      client = MetadataUtils.attachHeaders(client, metadata);
      

    3. Config JSON

    Protoc에서 생성된 nest_pb2NestRequest 객체를 통해 스트리밍 엔드포인트로 전달되는 Config JSON에 대해 설명합니다. Config JSON은 실시간 스트리밍 인식 API를 처음 호출 시 전송해야 합니다.
    Config JSON에는 다음과 같은 필드를 제공하고 있습니다.

    • transcription: 음성 인식 언어 설정
    • keywordBoosting: 입력된 단어들에 대해 인식률을 높이는 설정
    • forbidden: 금칙어 설정
    • semanticEpd: 음성 인식 결과 생성 기준 설정

    요청 바디

    Config JSON의 요청 바디에 대한 설명은 다음과 같습니다.

    Transcription

    Transcription에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    languageStringRequired음성 인식 대상 언어 코드
    • ko | en | ja
      • ko: 한국어
      • en: 영어
      • ja: 일본어
    참고

    transcription은 필수 입력 필드는 아니지만 명확한 음성 인식을 위해 설정하는 것을 권장합니다.

    Keyword Boosting

    Keyword Boosting 필드에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    keywordBoostingObjectOptional키워드 부스팅 정보
    • 미리 등록한 키워드에 대한 인식률 향상
    keywordBoosting.boostingsArrayOptional키워드 부스팅 단어 상세 정보

    boostings

    keywordBoosting.boostings에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    wordsStringOptional키워드 부스팅 단어 목록
    • 다중 입력 시 콤마(,)로 연결
      • <예시> "words": "test,test1,test2"
    • 단어 앞뒤 공백(space) 포함
    weightFloatOptional키워드 부스팅 가중치
    • 0~5.0
      • 가중치가 0일 경우 부스팅 미적용
    • 모든 키워드의 가중치는 동일

    Forbidden

    Forbidden 필드에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    forbiddenObjectOptional금칙어 정보
    • 미리 등록한 키워드에 대한 인식률 저하
    forbidden.forbiddensStringOptional금칙어 목록
    • 다중 입력 시 콤마(,)로 연결
      • <예시> "forbiddens": "금칙어1, 금칙어2"
    • 단어 앞뒤 공백(space) 포함
    • 금칙어 태그: <forbidden>금칙어</forbidden>
      • 인식 결과 내 text 키의 값에만 추가
      • 추가된 태그는 인식 결과의 position, periodPosition, alignInfo에 영향 없음

    SemanticEpd

    SemanticEpd 필드에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    semanticEpdObjectOptional음성 인식 결과의 생성 기준 설정 정보
    semanticEpd.skipEmptyTextBooleanOptional인식 결과가 없는 결과 값의 전송 여부
    • true | false (기본값)
      • true: 미전송
      • false: 전송
    semanticEpd.useWordEpdBooleanOptional단어(word)로 종료하는 인식 결과 생성 여부
    • true | false (기본값)
      • true: 생성
      • false: 미생성
    semanticEpd.usePeriodEpdBooleanOptional구두점으로 종료하는 인식 결과 생성 여부
    • true | false (기본값)
      • true: 생성
      • false: 미생성
    • 구두점 인식 정확도 향상을 위해 usePeriodEpdtrue인 경우 useWordEpdtrue로 설정
    semanticEpd.gapThresholdIntegerOptional인식 결과 생성 기준 묵음 발생 시간(ms)
    • gapThreshold 이상의 묵음 발생 시 인식 결과 생성
    • 기본적으로 gapThreshold 사용하지 않으며, 사용자가 따로 설정하지 않거나 0 이하 값 설정 시에도 미사용
    semanticEpd.durationThresholdIntegerOptional인식 결과 생성 기준 지속 시간 (ms)
    • 인식 결과의 지속 시간이 durationThreshold 값보다 작을 시 인식 결과 생성
    • 기본적으로 durationThreshold 사용되며, 사용자가 따로 설정하지 않거나 0 이하의 값 설정 시 기본값으로 설정됨
    semanticEpd.syllableThresholdIntegerOptional인식 결과 생성 기준 음절의 개수
    • 인식 결과를 구성하는 음절의 개수가 syllableThreshold 값보다 작도록 인식 결과 생성
    • 공백(" ")과 마침표(".")도 하나의 음절로 처리
    • 기본적으로 syllableThreshold 사용하지 않으며, 사용자가 따로 설정하지 않거나 0 이하의 값 설정 시에도 미사용

    요청 예시

    Config JSON의 요청 예시는 다음과 같습니다.

    {
      "keywordBoosting": {                  
        "boostings": [
          {
            "words": "test,test1,test2",
            "weight": 1
          },
          {
            "words": "테스트,테스트1,테스트2",
            "weight": 0.5
          }
        ],
      },
      "forbidden": {
        "forbiddens":  "금칙어1,금칙어2",
      }
    }
    

    응답 바디

    Config JSON의 응답 바디에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    uidString-UID
    responseTypeArray<String>-응답 유형
    • transcription | keywordBoosting | Forbidden | semanticEpd
    configObject-Config JSON 정보
    config.statusString-Config JSON 요청 상태
    • Success | Failure | ${message}
      • Success: 요청 성공(gRPC 내 설정 저장 완료)
      • Failure: 요청 실패(오류 메시지) 참조
      • ${message}: top_level_key 생략 가능
    config.keywordBoostingObject-키워드 부스팅 정보
    config.keywordBoosting.statusString-키워드 부스팅 요청 상태
    • Success | Failure | ${message}
      • Success: 요청 성공(gRPC 내 설정 저장 완료)
      • Failure: 요청 실패(오류 메시지) 참조
      • ${message}: top_level_key 생략 가능
    config.forbiddenObject-민감 키워드 정보
    config.forbidden.statusString-민감 키워드 요청 상태
    • Success | Failure | ${message}
      • Success: 요청 성공(gRPC 내 설정 저장 완료)
      • Failure: 요청 실패(오류 메시지) 참조
      • ${message}: top_level_key 생략 가능
    config.semanticEpdObject-Semantic EPD 정보
    config.semanticEpd.statusString-Semantic EPD 요청 상태
    • Success | Failure | ${message}
      • Success: 요청 성공(gRPC 내 설정 저장 완료)
      • Failure: 요청 실패(오류 메시지) 참조
      • ${message}: top_level_key 생략 가능

    오류 메시지

    요청 실패 시 나타나는 오류 메시지에 대한 설명은 다음과 같습니다.

    오류 메시지연관 필드설명
    Unknown key: ${top_level_key}-${unknown_key}공통서버 미지원 서브 레벨 키(Sub Level Key) 보유
    Invalid type: ${top_level_key}-${invalid_type_key}공통서버 미지원 서브 레벨 밸류 타입(Sub Level Value Type) 보유
    Invalid language code: ${invalid_language_code}transcriptionlanguage가 사전 정의되지 않은 언어 코드
    Not Authorizedtranscriptionlanguage가 허용되지 않은 언어 코드
    Internal system errorkeywordBoosting서버 내부 문제 발생
    Invalid request json format-비정상적인 JSON 형식
    Required key is not provided-서버에 정의된 필수 키 값 미포함
    No more slot-현재 서버에 여유 자원이 없음
    ConfigRequest did not complete-Config JSON 요청 처리 미완료 상태에서 서버에 인식 요청
    Lifespan expired-gRPC 서비스 사용 시간 만료
    • 기준: 100 시간
    Failed to received request msg-서버가 요청 메시지를 정상 수신하지 못함
    Model server is not working-서버 내부 오류
    Internal server error-서버 내부 오류

    응답 예시

    Config JSON의 응답 예시는 다음과 같습니다.

    성공

    호출이 성공한 경우의 응답 예시는 다음과 같습니다.

    {
      "uid": "{uid}",
      "responseType": [ "config" ],
      "config": {
        "status": "Success",
        "keywordBoosting": {
          "status": "Success"
        },
        "forbidden" : {
          "status": "Success"
        }
    }
    

    실패

    요청에 hobidden 입력 시 호출이 실패한 경우의 응답 예시는 다음과 같습니다.

    {
      "uid": "{uid}",
      "responseType": [ "config" ]
      "config": {
        "status": "Unknown key: hobidden"
      }
    }
    

    4. 인식(Recognize)

    Config JSON을 통해 원하는 설정을 진행한 후 recognize를 통해 음성 인식 API를 호출하여 실시간으로 음성 데이터를 처리하여 인식합니다. Protoc에서 생성한 코드에 있는 NestRequest와 인증 메타 데이터를 stub의 메서드인 recognize를 통해 음성 인식 API를 호출하게 됩니다.

    요청 바디

    Recognize의 요청 바디에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    epFlagBooleanOptional일시 정지 또는 마지막 인식 요청 시 버퍼 및 결과 반환 시점
    • true | false (기본값)
      • true: 인식 요청 버퍼 즉시 반환 후 결과 반환
      • false: 10초 동안 추가 요청 없을 경우 버퍼 자동 반환 후 결과 반환
    seqIdIntegerConditional인식 요청 아이디
    • epFlagtrue일 떄 결과 확인 용도로 사용
    • seqId 설정 후 미전송 시 결과값 0
      • 0 이외 값으로 설정 및 전송 권장

    응답 바디

    Recognize의 응답 바디에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    uidString-UID
    responseTypeArray-응답 유형
    • transcription | keywordBoosting | Forbidden | semanticEpd | recognize
    configObject-Config JSON 필드 정보
    config.textString-인식 결과 텍스트
    config.positionInteger-전체 텍스트에서 text로 전달 받은 텍스트의 위치
    config.periodPositionsArray<Integer>-전체 텍스트에서 .(구두점)의 위치
    • text.이 없을 경우 공백
    config.periodAlignIndicesArray<Integer>-.alignInfos 인덱스 정보
    • text.이 없을 경우 공백
    config.epFlagBooleanOptional요청에서 epFlagtrue로 설정하고 보낸 음원에 대한 인식 결과 포함 여부
    • true | false
      • true: 포함
      • false: 포함 안함
    config.seqIdInteger-인식 결과의 마지막 요청 여부
    • true | false
      • true: 마지막 인식 요청의 seqId 반환
      • false: 0 반환
    config.epdTypeString-인식 결과 생성에 대한 EPD 기준
    • gap | endPoint | durationThreshold | period | syllableThreshold | unvoice
      • gap: 묵음
      • endPoint: 마지막 음성 데이터 조각
      • durationThreshold: 재생 시간
      • period: 구두점
      • syllableThreshold: 음절 개수
      • unvoice: unvoiceTime(서버 설정) 수행
    config.startTimestampInteger-인식 결과 시작 시각(ms)
    config.endTimestampInteger-인식 결과 종료 시각(ms)
    config.confidenceFloat-인식 결과 신뢰도
    • 인식 결과의 모든 음절 신뢰도(alignInfos.confidence)의 기하 평균값
    config.alignInfosArray-인식 결과 구성 음절의 Align 정보
    recognizeObject-인식(Recognize) 정보
    recognize.statusString-인식(Recognize) 상태
    recognize.epFlagObject-epFlag 정보
    recognize.epFlag.statusString-epFlag 상태
    • 인식(Recognize) 요청 JSON에 extraContents가 유효하지 않은 형식일 경우 epFlag.status 또는 seqId.status에 실패 상세 이유 표시
    • 응답 실패의 경우 오류 메시지 참조
    recognize.seqIdObject-seqId 정보
    recognize.seqId.statusString-seqId 상태
    • 인식(Recognize) 요청 JSON에 extraContents가 유효하지 않은 형식일 경우 epFlag.status 또는 seqId.status에 실패 상세 이유 표시
    • 응답 실패의 경우 오류 메시지 참조
    참고

    textposition을 사용하여 full text를 구성하는 예시는 다음과 같습니다.

    전달 받은 순서인식 결과full text
    1{text: "가나다", position: 0, ...}"가나다"
    2{text: "라마바사", position: 3, ...}"가나다라마바사"

    alignInfos

    config.alignInfos에 대한 설명은 다음과 같습니다.

    필드타입필수 여부설명
    wordString-구성 음절
    startInteger-구성 음절 시작 시각(ms)
    endInteger-구성 음절 종료 시각(ms)
    confidenceFloat-구성 음절 신뢰도
    • 0~1.0

    오류 메시지

    Recognize 요청 실패 시 나타나는 오류 메시지에 대한 설명은 다음과 같습니다.

    오류 메시지연관 필드설명
    Invalid Typerecognize.statusepFlag 또는 seqId 타입과 사전 정의된 타입 불일치
    Required key is not providedrecognize.statusextraContentsepFlag 값 미전달
    Invalid request json formatrecognize.statusextraContents가 JSON 형식이 아님
    Unknown keyrecognize.statusextraContents에 프로토콜에 없는 key 작성
    ConfigRequest is already calledrecognize.status서버에 Config 요청 중복
    Lifespan expiredrecognize.statusgRPC 서비스 사용 시간 만료
    • 기준: 100 시간
    Failed to received request msgrecognize.status서버가 요청 메시지를 정상 수신하지 못함
    Model server is not workingrecognize.status서버 내부 문제 발생
    Internal server errorrecognize.status서버 내부 문제 발생
    Invalid formatrecognize.status전송한 오디오 형식이 유효하지 않음
    Not foundepFlag.statusepFlag 값 미입력
    Invalid typeepFlag.status, seqId.status사전 정의된 타입 불일치
    Invalid formataudio.statusaudio 필드 사전 정의된 타입 불일치

    응답 예시

    응답 예시는 다음과 같습니다.

    성공

    호출이 성공한 경우의 응답 예시는 다음과 같습니다.

    • 응답 성공 및 "responseType": [ "transcription" ]일 때
    {
      "uid": "{uid}"
      "responseType": [ "transcription" ]
      "transcription": {
        "text": "입니다.",
        "position": 0,
        "periodPositions": [3],
        "periodAlignIndices": [3],
        "epFlag": false,
        "seqId": 0,
        "epdType": "durationThreshold",
        "startTimestamp": 190,
        "endTimestamp": 840,
        "confidence": 0.997389124199423,
        "alignInfos": [
          {"word":"입","start":190,"end":340,"confidence":0.9988637124943075},
          {"word":"니","start":341,"end":447,"confidence":0.9990018488549978},
          {"word":"다","start":448,"end":580,"confidence":0.9912501264550316},
          {"word":".","start":581,"end":700,"confidence":0.9994397226648595},
          {"word":" ","start":701,"end":840,"confidence":0.9984142043105126}
        ]
      }
    }
    

    실패

    호출이 실패한 경우의 응답 예시는 다음과 같습니다.

    {
      "uid": string,                     # required
      "responseType": [ "recognize" ],    # required
      "recognize": {                     # required
        "status": string,                # required
        "epFlag": {                      # optional
          "status": string
        },
        "seqId": {                       # optional
          "status": string
        },
        "audio": {                       # op
          "status": 
        }
      }
    }
    

    이 문서가 도움이 되었습니까?

    What's Next
    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.