LangChain Agent를 활용한 음성 인증 봇

최근 음성 인식을 통해 사용자의 신원을 확인하는 기술이 점점 더 많이 활용되고 있다.

인공지능 모델을 통해서 본인인지 아닌지 체크(목소리 인증)하는 부분은 모델을 따로 찾지 못해 학습을 진행하여 구현했다.
학습된 모델 링크 : https://huggingface.co/Songhun/wav2vec2-base-960h-contrastive

LLM 모델이 목소리 인증을 하는 부분을 사용할 수 있도록 function call로 불러와서 사용할 수 있도록 agent를 이용


  1. 필요 라이브러리 import

import os

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import AIMessage, HumanMessage
from langchain.agents import create_tool_calling_agent
from langchain.agents import AgentExecutor, create_tool_calling_agent, tool
from langchain_community.tools.tavily_search import TavilySearchResults
import speech_recognition as sr
from playsound import playsound
import librosa
import torch
import torch.nn.functional as F
from transformers import Wav2Vec2Model, AutoFeatureExtractor
from torch.nn.functional import cosine_similarity

from dotenv import load_dotenv
load_dotenv()

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY_songhun")


  1. function calling에 사용될 함수 선언


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def load_and_process_audio(file_path, feature_extractor, max_length=4.0):
    audio, sampling_rate = librosa.load(file_path, sr=16000)
    inputs = feature_extractor(audio, sampling_rate=sampling_rate, return_tensors="pt", padding="max_length", truncation=True, max_length=int(max_length * sampling_rate))
    return inputs.input_values.to(device)

def get_voice_similarity():
    model_name = "Songhun/wav2vec2-base-960h-contrastive"
    voice_model = Wav2Vec2Model.from_pretrained(model_name).to(device)
    feature_extractor = AutoFeatureExtractor.from_pretrained(model_name)
    audio_input1 = load_and_process_audio('./anchor_voice.wav', feature_extractor).to(device)
    audio_input2 = load_and_process_audio('./saved_voice.wav', feature_extractor).to(device)

    embedding1 = voice_model(audio_input1).last_hidden_state.mean(dim=1)
    embedding2 = voice_model(audio_input2).last_hidden_state.mean(dim=1)

    similarity = F.cosine_similarity(embedding1, embedding2).item()

    voice_return = False
    if similarity > 0.3331:
        voice_return = True
    print(f"Similarity: {similarity}")
    return voice_return, similarity

@tool
def get_voice_and_verify():
    """
    This function is executed when voice authentication is required.
    This function records audio and saves it, and then calculates the similarity to verify if it's the same voice.
    this function return voice_return(True, False), similarity(Voice Similarity Score)
    """
    r = sr.Recognizer()
    mic = sr.Microphone()
    with mic as source:
        print("녹음 시작...")
        audio_data = r.listen(source)
        print("녹음 완료!")

    with open('./saved_voice.wav', "wb") as f:
        f.write(audio_data.get_wav_data())

    return get_voice_similarity()

음성 유사도 비교는 간단하게 현재 directory에 기준이 되는 “anchor_voice.wav“ 파일을 미리 준비하고 LLM의 function call에 따라 함수가 호출될 때 사용자의 목소리”saved_voice.wav”가 저장된다.
두 목소리의 유사도가 비교된다.


  1. main함수 작성 (모델 선언, agent 선언)


def main():
    model = ChatOpenAI(model="gpt-4o", openai_api_key=OPENAI_API_KEY)
    prompt = ChatPromptTemplate.from_messages([
        ('system', '너는 유용한 인공지능 조수야'),
        ("placeholder", "{chat_history}"),
        ("human", "{input}"),
        ("placeholder", "{agent_scratchpad}"),
    ])

    tools = [get_voice_and_verify]
    agent = create_tool_calling_agent(model, tools, prompt)
    agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
    
    chat_history = []

    while True:
        input_text = input("궁금한걸 물어보세요:")
        if input_text=='exit':break

        chat_history.append(HumanMessage(content=input_text))

        ans = agent_executor.invoke(
            {
                "input": input_text,
                "chat_history": chat_history,
            }
        )

        chat_history.append(AIMessage(content=ans['output']))
        print(f"에이전트: {ans}")
    print('종료합니다.')


[ Curious ]

  • History 관리를 이렇게 해도 되나?


# 11기 랭체인

8
1개의 답글

👉 이 게시글도 읽어보세요