Seems like Camomile can do it: https://github.com/yoriyuki/Camomile/blob/d7d8843c88fae774f513610f8e09a613778e64b3/Camomile/public/charEncoding.mli#L89
E.g.
utop # #require "camomile";;
utop # module Camomile = CamomileLibraryDefault.Camomile;;
utop # module Enc = Camomile.CharEncoding;;
utop # let gbk = Enc.of_name "GBK";;
val gbk : Enc.t = <abstr>
utop # Enc.recode_string ~in_enc:Enc.utf8 ~out_enc:gbk "Hello";;
- : string = "Hello"
Of course in your case you want to go in the opposite direction, so switch the ‘in’ and ‘out’ encodings. Check your installed packages, you may already have Camomile as a transitive dep.