LLM이 다양한 분야에서 활용되면서 모델이 생성해서는 안 되는 내용을 어떻게 막을 것인지가 중요한 문제가 되고 있습니다. 대표적으로 욕설, 혐오 표현, 개인정보(PII), 민감한 식별 정보 등이 있습니다. 기존에는 LLM이 답변을 생성한 뒤, 사후적으로 금지어를 찾아 마스킹하거나 삭제하는 방식이 많이 사용되었습니다. 하지만 이런 post-processing 방식은 이미 문제가 되는 문장이 생성된 뒤에야 개입하기 때문에, 최종 출력에 어색한 마스킹 흔적이나 갑작스러운 삭제가 생기고 문장의 자연스러움이 떨어진다는 한계가 있습니다.
이에 대한 대안으로 constrained decoding이 사용됩니다. 이는 LLM이 토큰을 생성하는 과정에서 제약 조건을 위반할 가능성이 있는 토큰을 미리 제거하는 방식입니다. 하지만 기존 constrained decoding 연구는 주로 출력이 어떤 형식에 맞아야 한다는 positive constraint에 초점을 맞추었습니다. 반면 실제 안전성 문제에서는 어떤 문자열이나 패턴이 절대 등장하면 안 된다는 negative constraint가 더 중요합니다. 이 논문은 바로 이러한 문제를 해결하기 위해 NCO(Negative COnstrained) Decoding을 제안합니다.
Negative constraint는 단순히 특정 토큰을 금지하는 문제와 다릅니다. 예를 들어 전화번호 형식인 000-000-0000을 막고 싶다고 할 때, 이 패턴은 하나의 토큰으로 생성되지 않을 수 있습니다. 여러 토큰이 이어지면서 최종적으로 금지된 패턴이 완성될 수 있기 때문에, 단순 blacklist 방식으로는 이를 막기 어렵습니다.
이론적으로는 금지 문자열이나 정규식을 하나의 거대한 automaton으로 변환한 뒤, 생성 과정에서 해당 automaton을 추적하는 방식이 가능합니다. 하지만 여러 개의 금지 조건을 동시에 처리하면 automaton의 상태 수가 매우 커질 수 있습니다. 특히 어떤 금지 패턴이 출력의 어느 위치에서든 substring으로 등장하면 안 되는 경우, 가능한 시작 위치를 모두 추적해야 하므로 상태 폭발 문제가 발생합니다.

위 그림은 NCO가 해결하려는 문제를 잘 보여줍니다. 사용자가 “Tom의 전화번호를 알려줘”라고 묻고, 출력이 전화번호 정규식 [0-9]{3}-[0-9]{3}-[0-9]{4}와 매칭되면 안 된다는 제약이 주어진 상황입니다. 일반 LLM은 실제 전화번호를 그대로 출력해 제약을 위반할 수 있습니다. 기존 방식들은 제약 위반을 막을 수는 있지만, 추가적인 검사나 재샘플링 때문에 느려집니다. 반면 NCO는 생성 중 invalid continuation을 미리 억제하여 제약을 만족하면서도 빠른 생성을 유지합니다.
NCO는 LLM 자체를 수정하거나 fine-tuning하지 않고, 생성 과정의 logit level에서 개입하는 plug-in 방식의 디코딩 기법입니다. 각 decoding step에서 현재까지 생성된 prefix를 기준으로, 다음에 올 수 있는 vocabulary token 중 금지 문자열이나 금지 정규식을 완성할 가능성이 있는 token을 찾아 mask 처리합니다.
즉, NCO는 다음 토큰 후보 중에서 제약을 위반하는 토큰의 logit을 음의 무한대로 만들어 선택되지 않도록 합니다. 이후에는 greedy decoding, top-k sampling, top-p sampling, temperature sampling, beam search 등 기존의 표준 decoding 방법을 그대로 사용할 수 있습니다.
NCO의 중요한 설계 원칙은 모든 제약을 하나의 거대한 automaton으로 합치지 않는 것입니다. 대신 제약들을 따로 유지하면서, 각 제약이 현재 상태에서 어떤 token을 금지하는지만 계산하고, 그 mask들을 결합합니다. 이를 통해 상태 폭발을 피하고 batch generation 환경에서도 효율적으로 동작합니다.

위 그림은 NCO의 전체 구조를 보여줍니다. 먼저 금지 문자열이나 정규식 패턴을 입력으로 받아 constraint automata를 구성합니다. 이후 BPE 기반 precomputation을 통해 각 token이 automaton 상태를 어떻게 변화시키는지 미리 계산합니다. 실제 decoding 단계에서는 현재 상태에 맞는 mask를 조회하고, 이를 model logits에 적용한 뒤 기존 sampling strategy를 수행합니다.
NCO는 크게 두 종류의 negative constraint를 처리합니다.