들어가며

최근 GeeksNews에서 GPT를 이용한 벡엔드 서버에 관한 기사를 봤습니다(https://news.hada.io/topic?id=8341). 벡엔드 개발자로서는 굉장히 흥미로운 주제이기 때문에 어떻게 구현되어있는지 알아보았습니다. 이 포스트에서는 그 결과와 한계에 대해서 설명해보고자 합니다.

Backend-GPT란?

기존 벡엔드 서버는 코드를 이용해서 구현했습니다. Backend-GPT는 코드를 이용한 구현은 버그, 리뷰 필요 그리고 우리가 원하는 비즈니스 로직이 아닌 우리가 말하는 것만 수행한다고 비판하는 것에서 시작합니다. 비즈니스 로직을 처리하기 위해선 인간의 지능이 적절한 형태라고 말합니다. 이 문제를 해결하기 위해 LLM(Large-Language Model, ex.GPT) 을 벡엔드 서버로 처리자로 구현한 것이 Backend-GPT입니다.

Backend-GPT의 구현

코드를 분석한 결과 구현은 매우 간단합니다. 초기 데이터베이스 상태를 표현하는 JSON과 전달된 API를 GPT 모델에 전달하고, 계산된 API 결과와 데이터베이스 결과를 받아옵니다. 그리고 다시 API가 요청이 오면 갱신된 데이터베이스 결과와 API를 다시 전달합니다. 코드를 자세히 알아보면 다음과 같습니다.(2023.1.30 기준, 로그와 같은 불필요한 코드는 임의로 삭제했습니다.)

import json
from flask import Flask
import ray
ray.init()
from flask_cors import CORS
import requests

@ray.remote
def gpt3(input):
    response = requests.post(
    "<https://dashboard.scale.com/spellbook/api/app/kw1n3er6>",
    json={
            "input": input
        },
    headers={"Authorization":"Basic cld6n7eoo0065sr1acbwczykv"}
    )
    return response.text

def dict_to_json(d):
    return d.__dict__

app = Flask(__name__)
CORS(app)
db = json.load(open('db.json','r'))

@app.route('//') --------------- 1.
def api(app_name, api_call):
    db = json.load(open('db.json','r'))--------------- 2.
    gpt3_input = f"""{db[app_name]["prompt"]}
API Call (indexes are zero-indexed):
{api_call}
Database State:
{db[app_name]["state"]}
Output the API response prefixed with 'API response:'. Then output the new database state as json, prefixed with 'New Database State:'. If the API call is only requesting data, then don't change the database state, but base your 'API Response' off what's in the database.
""" --------------- 3.
    completion = ray.get(gpt3.remote(gpt3_input)) --------------- 4.
    completion = json.loads(completion)["text"]

    future1 = gpt3.remote(f"{completion}\\n\\nAPI Response as valid json (as above, ignoring new database state): ")
    future2 = gpt3.remote(f"{completion}\\n\\nThe value of 'New Database State' above (as json):")
    response = json.loads(ray.get(future1).strip())["text"].strip()
    new_state = json.loads(json.loads(ray.get(future2).strip())["text"].strip())
    db[app_name]["state"] = new_state
--------------- 5.
    json.dump(db, open('db.json', 'w'), indent=4, default=dict_to_json) --------------- 6.
    return response --------------- 7.

if __name__ == "__main__":
    app.run()
  1. Flask로 HTTP API 인터페이스 구현
  2. API 요청이 오면 현재 데이터베이스 상태를 로드
  3. API와 데이터베이스 상태를 바탕으로 GPT에 질문할 문장을 생성
  4. GPT에 질문 전송
  5. 데이터 수신 및 파싱
  6. 데이터베이스 상태 업데이트
  7. 응답 전달

한계

위 코드를 보면 알겠지만, 데이터를 전달할 때마다 데이터베이스 상태를 전달합니다. GPT가 수신할 수 있는 문장 길이는 제한되어 있기 때문에, 레포지토리에는 1KB 내외의 데이터만 가능하다고 명시되어 있습니다. 여기서 제가 추가적으로 생각하는 한계를 포함하면 다음과 같습니다.

  • 매우 제한적인 데이터베이스 용량 ~ 1KB
  • GPT API 사용으로 인한 매우 제한적인 트래픽
  • 파일시스템 기반의 동시성 처리 문제
  • 매번 데이터베이스 전체 상태 전달과 GPT 계산으로 인한 낮은 속도
  • 높은 추상화로 인한 최적화 설정 한계
  • 동일한 결과 미보장(GPT가 지속적으로 학습을 할 경우)

응용

위 한계로 인해서 응용할 수 있는 조건은 다음과 같이 매우 제한적입니다.

  1. 1KB 이내의 데이터 용량만 다루는 경우
  2. 사용자가 매우 적은 경우(정확한 수치는 계산 필요)
  3. 동시성 처리가 필요없거나 동시 사용자가 한 명으로 보장된 경우
  4. 빠른 속도가 필요하지 않은 경우
  5. 결과의 동일성이 반드시 보장되지 않아도 되는 경우

평가

위 응용 조건으로 인해서 현재 Backend-GPT 를 현업에 도입하는 것은 매우 어려울 것으로 보입니다. 그러나 별도의 코드 작성없이 서버 기능을 구현한다는 점에서 높은 효과성을 가지고 있습니다. 개발과정에서 위 응용조건에 부합하는 경우는 MVP 개발이나 Mock API 정도가 있을 것 같습니다. 

Reference

+ Recent posts