🤖 Computer Science
세션 5. 모바일 게임에 강화학습 적용하기
박주형 ( 스메일게이트 메가포트 )
현업에서 RL을 적용할 때에 있어서 시행착오를 공유
출처!
학습 방법
Observation
- Spatial
- Non-Spatial Features
- 일반적인 1D data. (예: HP/MP, 공격력, 방어력 … 등등)
- 대부분의 데이터가 Non-Spatial
- Scalar 값
- -1.0 ~ 1.0 사이로 Normalize
- Min/max 값을 알기 힘든 경우 또는 너무 값이 큰 경우 적당한 값으로 truncation 필요
- Categorical 값
- 숫자가 직접적인 의미를 가지지 않는 경우 ( Unit ID, Skill ID, Buff ID … 등)
- 스칼라처럼 Normalize를 하면 학습이 전혀 되지 않음
- 기본적으로는 One-hot Encoding으로 변환후 사용, ID의 종류가 많으면 Embedding
- 200~300개 정도 되더라도 Spatial Feature보다는 사이즈가 작기 때문에 One-hot Encoding으로 하는게 오히려 잘 됐다.
- HP 표현 방식
- 구간에 따라 서로 다른 가중치를 주는 방식을 사용할 수 있다
- 알파 스타의 경우

주황색의 그래프를 띄는데
HP가 작은 구간에서는 섬세하고 촘촘하게 여러 구간 표현, 높은 구간에서는 적게 표현
간단하면서 좋은 아이디어라 많이 사용했다.
- Spatial Features
- 공간적인 모든 정보에 대해서 표현
- 예: 아군/적군의 위치, Height, 아이템 위치, Skill 범위 …
- 사이즈가 크기 때문에 축소 시킬 수 있는 방법을 찾아야함
- 겹치지 않는 정보의 경우 같은 채널에서 표시할 수 있다.
- 겹치는 경우에는 이를 채널 별로 분리하거나 한 번에 다 표시하다가 그 중에 중요한 애를 (Rule-based)로 골라서 하나만 표시하게끔 해도 문제없이 잘 작동했다.
- Image를 입력으로 왜 사용하지 않는가? ( 아타리도 인풋이미지로 사용하는데 .. )
- 당연히! 잘 안되니까 사용하지 않는다
- 100x100이나 320x240으로 줄여도 굉장히 사이즈가 크다
- 학습을 안되게 하는 요인
- Enter the gundeon 같은 경우에도 2D로 단순한데
- 자잘한 이펙트가 너무 많아 학습이 안된다
- Unreal 5 의 경우 조도에 따라서 이미지가 너무 달라진다.
- 시뮬레이터에서 이미지 Rendering 자체가 매우 부하가 많은 작업
- 공간 정보가 필요한 경우 spatial feature 형태로 사용
- 기타 고려할 점
- Feature 설계할 때 사람이 인지할 수 있는 웬만한 것을 모두 표현 할 수 있도록 노력
- Observation과 Feature 끼리 조합해서 새로운 Observation을 만들 수 있다.
- 플레이어가 확인 할 수 없는 정보를 포함해도 크게 문제가 없다. (최대한 정보가 많을 수록 좋다 )
- 일단 학습이 잘 되게 하면, 그 다음에 하나씩 쳐내는게 쉽다
- 가능한 모든 데이터를 확보해서 학습 → 학습이 잘 되는거 자체가 어렵기 때문
- 일반적으로 Spatial Feature의 데이터양이 크므로 적절하게 사이즈를 조절하는것이 필요하다.
Model
Architecture

- Non-spatial : 1D Conv
- spatial : 2D Conv
- other(Map, Turn … ) : 개수가 작으면 바로 Concat, 크면 Conv 태워서 Concat
이 3개를 FC layer에 태워서
캐릭터의 Action Policy와 Move Action Policy를 산출
이 구조에서 여러가지 Transformer나 Self-Attention 구조를 테스트 해볼 수 있을 것이다.
추가로 Attention 구조가 좋은게
어떤 의미를 가지냐? 캐릭터를 선택해야하는데, Non-spatial한 Character와 Attention을 걸면
일종의 Residual 효과를 나타내서 성능이 올라간다

캐릭터의 행동이 움직임에 영향을 주는 (concat) 구조가 있을 수도 있다. ( 게임마다 다름 )
일반적으로 크게 영향이 없었다

Self Attention ( from Transformer )
- 강화학습에서는 Unit이나 카드 feature에 사용할 경우 서로의 상성 관계를 계산
- Positional Encoding
- Unit이 많은 경우 사용해 볼 수 있음
- 대부분의 게임에서는 많지 않으므로 위치 index값 (one-hot)으로도 충분
Policy in auto-regressive manner
- 실제 게임에서 굉장히 많은 action이 있어서 학습이 잘 되지 않음
- 예를 들면 5개의 유닛이 하나를 선택 10개의 포지션 중 하나를 옮긴다음 4개의 스킬이 있으면 하나를 선택
- 단점은 action-value 함수를 사용하는 알고리즘은 사용 불가 (예: Acer)

일반적으로 Policy Output으로 하게되면
10*5*4로 200개가 나오게 된다. 개수가 많아져서 학습이 잘 안됨
200개 정도는 어느정도 될 만한데 몇 천개 몇 만개가 되면 힘들다
그래서 액션이 많으면 이 방법이 매우 유용하다 ( 학습이 잘 되기 때문에 )
Systems, Others
RL Algorithms
- 아무 생각이 없다면 PPO 부터 사용 ( A2C도 나쁘지 않음 )
- 우리가 만드는 게임이 스타2, 도타 보다 복잡하지 않는 이상 웬만한건 다 가능하다
- 알고리즘에 따라 학습 결과가 극적으로 바뀌지 않는다
- 학습을 했는데 잘 안된다. 그럼 보통 시뮬레이션이나 피쳐 쪽에 버그가 있는 경우
- 어떤 알고리즘이라도 어느 정도 학습은 되어야 한다
- 초기에는 가급적 외부 라이브러리나 프레임 워크를 사용 권장
- 이외로 learning rate나 기타 parameter는 크게 영향을 미치지 않는다
분산 강화 학습
- 현업에서 학습을 하려면 시간이 굉장히 중요하다. 분산을 할 수 밖에 없다.
- 카드 수집형 게임도 학습을 하는데, 한 번에 끝나지 않고 필터링 해서 여러번 하는 경우가 많다.
- 하드웨어
- 내부 구축 ( 절대적으로 CPU가 많은게 유리하다 ) / AWS / GCP
- GPU는 액터가 시뮬레이터 배치 만드는 속도를 따라가지 못한다
- GCP의 경우 Spot 장비를 사용하면 비용을 1/4 정도로 줄일 수 있음
- 소프트웨어
- 자체 구현시 Ray 추천
- Impala 또는 PPO 추천
- Impala는 Tricky한 점이 V-Trace라는 알고리즘으로 Value, Policy 계산하는데
- Alphastar 에서 V-Trace말고 lambda return이 훨씬 잘 나왔다
- lambda return이 성능이 좋다
Self 학습
- PVP의 경우 Agent의 성능을 향상 시키기 위해서는 셀프 학습이 필수
- BT로 하게 되면 BT 이상 되지 않음
- 국룰: 평가모드 기준 55% 이상 승률을 기록하면 교체
- 정확히 대칭 상황인지 확인
- 승률도 잘 봐야한다
- 55% 이상 해서 교체하고 학습을 진행시켰는데, 학습 모드에서는 승률이 확 떨어져야 정상
- 근데 떨어지지 않고 55%를 유지하거나 그러면 버그
- 가위바위보 문제
- AI가 고도화 되는 것이 아니라 현재 상대한테만 이기는 전략을 학습
- 각 액터마다 묵찌빠가 몇개씩 있어야 한다
- 이전에 했던 애만 액터에 올리는게 아니라 그 이전, 그그 이전 것도 같이 일정한 비율로 섞어서 액터로 올리면 다양하게 학습이 되더라
- BT 같은 경우에도 초반에 쉽게 이겨서 Self로 넘어갔는데
- 나중에 BT를 상대 했더니 지는 경우가 나타났다
- 액터에 한 두개씩 BT를 끼워 넣으면 해결된다.
- 사람이랑 플레이를 잘하더라, 차원문이라는 기술을 쓰게 되면 잘 안되더라.. 게임 내에서 이 기술을 쓰는 경우가 굉장히 적어서, 잘 안됬던 것 → 액터가 몇 백개 있으면 스크립트로 그 중에 몇개는 강제로 주입 → 차원문도 잘 대응을 잘 하더라
- 액터를 어떻게 다양하게 할 것인가가 성능 향상의 전략이 된다.
- 알파 스타와 같이 리그전을 도입해도 되나 대부분 그정도로 복잡할 필요가 없다
Multi-Agent 학습
- 브롤스타즈 처럼 3v3 게임일때
- 하나의 Simulator에 3개의 Agent가 대응하여 액션을 뽑아주는 경우
- 하나의 에이전트가 각각 대응하는 경우


아래도 학습이 잘된다.
캐릭터가 여러개여도 각 상황별로 학습이 잘 된다.
3v3에서 1개만 플레이어고 나머지 BT 여도 승률이 60%였는데
아래 방식으로만 학습해도 승률이 90% 이상 나오더라
100%가 안되는 이유는 상성이 있기 떄문에
간단하게 적용해보고 전략적인게 필요하면 다른 알고리즘 사용
MA-POCCA ( ML-agent )
정리
- 이미지 대신 spatial / non-spatial 사용 추천
- 각각의 feature은 적절한 방법에 따라 변환
- Action이 많은 경우 auto-regressive 방식으로 표현
- 초기 알고리즘은 PPO나 A2C 추천
- 가급적 처음 학습 시에는 외부 라이브러리나 프레임워크를 사용하자
- Architecture의 경우도 처음부터 복잡할 필요가 없음
- 학습이 안된다면 알고리즘이나 학습 parameter를 바꾸기 보다는 feature/reward/action 등에 버그가 없는지 먼저 확인하자
Simulator
요구사항
- Atari Gym ( Gymnasium ) 형태로 python에서 리눅스로 돌아 가도록 만들어 주세요
- Step / Reset / Init 으로 동작
- Pause 지원
- 배속 지원
- Headless 모드로 동작
현실 세계
- 이 모든게 절대 당연하지 않다
- 그래픽과 게임 로직을 따로 분리하기가 힘들다 ( 이게 제일 힘들다 )
- GDC 2023 Riot games TFT RL 세미나 참고
- 개발자는 1년 365일 항상 바쁘고 개발 이외의 일은 매우매우매우 귀찮은 일ㅇ…
Pause 기능
- 경험상 처음부터 염두에 두고 개발하지 않는 이상 중간에 구현하기가 매우 어려움 ( 턴제 게임 예외 )
- 게임이 멈춘다는 것을 전제로 하지 않기 때문에
- 서버 까지 있는 경우 서버도 같이 Pause가 되어야 한다
- 가장 버그가 많이 일어날 수 있는 지점으로 지속적인 의사소통 필요
- 경우에 따라서는 Pause기능을 구현 못할 경우도 있으나 학습이 안되진 않음
배속 기능
- 대부분의 게임이 충돌이나 타격 시 그래픽 효과와 같이 엮여 있으므로 따로 로직 분리가 힘들다
- 유니티/언리얼 배속 기능을 지원하기는 하나 디버깅 필수
- 분산 환경만 잘 구축 하면 1배속에서 충분히 학습 할 수 있음
( 분산만 잘 되면 1배속이나 2배속이나 5배속이나 크게 차이 안난다 )
리눅스 빌드
- 대부분의 게임은 윈도우에서 개발됨
- 유니티나 언리얼은 리눅스 빌드를 지원하므로 리눅스 버전 사용가능
- 그 마저도 힘든 경우 Wine 등의 애뮬레이터를 사용하거나 윈도우에서 직접 학습
Headless
- 그래픽 끄는건데 보통 다 엔진에서 지원해줘서 쉽게 넘어감
정리
- 최대한 개발자의 사정을 파악하여 협조 요청
- 게임 개발 초기 부터 협업 하는 것이 가장 비용이 적다
- 필요하면 파견도 하겠다는 의지
- 가능한한 한 리플레이 뷰어 개발도 동시에 요청
Application
강화학습이 왜 필요한가요?
- 강화학습의 필요성을 어필해야 하는 경우가 많음
- 개발사나 사업부에서는 강하고 똑똑하기만 한 AI를 원하지 않음
- 오히려 져 주거나 적당히 사람 같은 AI를 원함
- 비용 문제

In-game AI
- 용도
- PVP에서 가상 매칭
- 즐겁게 져 줄수 있는 AI로 학습 해서 플레이어 만족도 업
- NPC나 보스/몬스터의 AI에 적용
- 단점
- 모델을 Inference 해야 하므로 서버의 경우 부하가 매우 커짐 → 경량화 필수
- 의도치 않은 동작을 할 수 있음 → 개발자가 매우 싫어하는 부분
- 긴급 버그가 발생한 경우 같이 불려 나감
적용했을때 만족감이 높다, ( 봇이라는 것을 잘 모름 ), 즐겁게 져주다 보니 의외로 만족도가 높다
져줄 수 있는 AI를 만드는 것도 여러가지 기법이 있다.
- Temperature을 조절하기도 하고
- Value가 승률을 나타내면 Peek 타이밍에 차선책의 액션을 선택
여러버전을 만든다음에 A/B 테스트를 진행했다.
어느게 가장 사람 같아요?
Balancing QA
- 가장 쉽고 효과적으로 사용할 수 있는 분야임
- 상관이 없음.. 라이브에 싣는 것도 아니고 그냥 안되면 안쓰면 돼고 이런 개념
- Agent가 플레이를 잘하니까 다량으로 플레이해서 통계 데이터를 바탕으로 수정
- 승률을 보고
- 어떤 스킬 데미지를 봐서
- 어떤 스킬이 제일 좋고
- 어떤 플레이어가 제일 좋은데
- 이게 기획자가 의도한 것이 맞냐? 아니면 수정
- 게임마다 워낙 데이터가 다양해서 미리 논의를 해야하고
- 밸런스 주기에 맞게 학습 결과를 전달 할 수 있어야 하기 때문에 속도를 빨리 해야한다
Technical QA
- 학습 중에 생각보다 버그를 찾아 내는 경우가 자주 있음
- 이를 전적으로 QA에 적용하여 QA를 위한 Agent를 학습
- EA에서 근래 많은 결과를 보여줌
개발이나 사업부에서 가장 원하는 것이 뭔지 파악 ( 비용, 밸런스 등 )
시작이 매우 중요 (Start Small) - 처음에 잘하면 일이 점점 들어온다..
강화학습은 게임 개발에 많은 도움이 된다.
디버깅 전략
- 강화학습 디버깅은 매우 어렵다
- 잘 안되는 경우 최대한 단순하게 해서 학습 테스트
- 리플레이 뷰어가 있는 경우 최대한 활용
- 학습 그래프만 보는 것은 크게 도움이 안됨
- 최대한 모든 observation을 저장해서 일일이 확인 → OpenCV
- 디버깅에 왕도는 없다. 최대한 많은 Log를 남기고 꼼꼼히 잘 살펴보자
강화학습 바이블
- 2017 : StarCraft II: a new challenge for reinforcement learning
- 2019 : Grandmaster level in StarCraft II using multi-agent reinforcement learning
- 2019 : Dota 2 with Large Scale Deep Reinforcement Learning