UTF−8 には濁点の扱いが2種類ある、というのは有名な話。例えば、「が」。

「か」

In [3]: u"か".encode("utf-8")
Out[3]: '\xe3\x81\x8b'

「が」

NKC

In [8]: unicodedata.normalize("NFC", u"が").encode("utf-8")
Out[8]: '\xe3\x81\x8c'

NFD

In [9]: unicodedata.normalize("NFD", u"が").encode("utf-8")
Out[9]: '\xe3\x81\x8b\xe3\x82\x99'

NFKC

In [11]: unicodedata.normalize("NFKC", u"が").encode("utf-8")
Out[11]: '\xe3\x81\x8c'

NFKD

In [10]: unicodedata.normalize("NFKD", u"が").encode("utf-8")
Out[10]: '\xe3\x81\x8b\xe3\x82\x99'

NKCはComposition、合成。だから「が」は 「か」から1ビットずれる 「x8b → x8c」

NKDはDecomposition、分解。だから「が」は「か+゛」なので「'\xe3\x81\x8b' + '\xe3\x82\x99'」

さて、では、「ガ」はどうなるだろうか?

In [46]: u"カ".encode("utf-8")
Out[46]: '\xe3\x82\xab'

In [44]: [unicodedata.normalize(_type, u"ガ").encode("utf-8") for _type in ("NFC", "NFD", "NFKC", "NFKD")]
Out[44]: 
['\xe3\x82\xac',
 '\xe3\x82\xab\xe3\x82\x99',
 '\xe3\x82\xac',
 '\xe3\x82\xab\xe3\x82\x99']

うん、法則は変わらない。

では、半角カナはどうだろうか?半角カナの濁点は「分解型」だよね。

In [89]: u"カ".encode("utf-8")
Out[89]: '\xef\xbd\xb6'

In [88]: [unicodedata.normalize(_type, u"ガ").encode("utf-8") for _type in ("NFC", "NFD", "NFKC", "NFKD")]
Out[88]: 
['\xef\xbd\xb6\xef\xbe\x9e',
 '\xef\xbd\xb6\xef\xbe\x9e',
 '\xe3\x82\xac',
 '\xe3\x82\xab\xe3\x82\x99']

半角カナは、NKFCのみ、合成型になる。そして、NFCとNFDは同じ。

ということで、Windows とか考えると無難なのはNFCなのかな?